Skip to content
Back to skills

solid-js-best-practices

ASecurity

Version-aware Solid.js best practices for AI-assisted coding, review, and migration. Use for Solid components, reactivity, state, DOM work, testing, React migration, and web component integration.

  • 2 stars
  • 0 votes
  • 0 copies
  • 9 views
  • Added October 14, 2026
ai-agentstypescriptgoreactnodetestingrefactoringgitapidatabaseperformance

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 20 files and shows the line behind each finding

Scanned October 14, 2026

npx -y skills add richardcarls/solid-js-best-practices --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of solid-js-best-practices?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for solid-js-best-practices
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/richardcarls-solid-js-best-practices/badge)](https://www.skillsdirectory.com/skills/richardcarls-solid-js-best-practices)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: solid-js-best-practices
description: "Version-aware Solid.js best practices for AI-assisted coding, review, and migration. Use for Solid components, reactivity, state, DOM work, testing, React migration, and web component integration."
license: MIT
allowed-tools:
  - Read
  - Grep
  - Glob
metadata:
  topics:
    - claude-skills
    - claude-code-skill
---

# Solid.js Best Practices

Comprehensive best practices for building Solid.js applications and components, optimized for
AI-assisted code generation, review, and refactoring.

## Version Routing

Read the project's `solid-js` version from its manifest and lockfile before applying code examples.
If the major is unknown, ask which major the project uses. The existing rule files are based on
Solid 1.x; `version_basis` records the version behind a rule, without limiting its principle to
that major. Do not copy a 1.x API example into a 2.x project without checking its current equivalent.
Solid 2.x coverage is deferred until its official release. For a pre-release 2.x project, consult
the [official 1.x migration guide](https://v2.solidjs.com/migration/from-solid-1) and documentation
for the installed release candidate; do not treat these 1.x rules as verified 2.x guidance.

## Rules by Category

### 1. Reactivity (7 rules)

| # | Rule | Priority | Description |
| - | ---- | -------- | ----------- |
| [1-1](rules/1-1-use-signals-correctly.md) | Use Signals Correctly | CRITICAL | Always call signals as functions `count()` not `count` |
| [1-2](rules/1-2-use-memo-for-derived.md) | Use Memo for Derived Values | HIGH | Use `createMemo` for computed values, not `createEffect` |
| [1-3](rules/1-3-effects-for-side-effects.md) | Effects for Side Effects Only | HIGH | Use `createEffect` only for side effects, not derivations |
| [1-7](rules/1-7-no-primitives-in-reactive-contexts.md) | No Primitives in Reactive Contexts | HIGH | Don't call hooks or create reactive primitives inside effects or memos |
| [1-4](rules/1-4-avoid-signal-in-effect.md) | Avoid Setting Signals in Effects | MEDIUM | Setting signals in effects can cause infinite loops |
| [1-5](rules/1-5-use-untrack-when-needed.md) | Use Untrack When Needed | MEDIUM | Use `untrack()` to prevent unwanted reactive subscriptions |
| [1-6](rules/1-6-batch-signal-updates.md) | Batch Signal Updates | LOW | Use `batch()` for multiple synchronous signal updates |

### 2. Components (10 rules)

| # | Rule | Priority | Description |
| - | ---- | -------- | ----------- |
| [2-1](rules/2-1-never-destructure-props.md) | Never Destructure Props | CRITICAL | Destructuring props breaks reactivity |
| [2-6](rules/2-6-components-return-once.md) | Components Return Once | CRITICAL | Never use early returns; use `<Show>`, `<Switch>`, etc. in JSX |
| [2-9](rules/2-9-never-call-components-as-functions.md) | Never Call Components as Functions | CRITICAL | Always use JSX or `createComponent()`; direct calls leak reactive scope |
| [2-2](rules/2-2-use-merge-props.md) | Use mergeProps | HIGH | Use `mergeProps` for default prop values |
| [2-3](rules/2-3-use-split-props.md) | Use splitProps | HIGH | Use `splitProps` to separate prop groups safely |
| [2-7](rules/2-7-no-react-specific-props.md) | No React-Specific Props | HIGH | Use `class` not `className`, `for` not `htmlFor` |
| [2-10](rules/2-10-custom-element-typescript-declarations.md) | Custom Element TypeScript Declarations | HIGH | Declare custom element tags in JSX namespace; augment DOM types for newer attributes |
| [2-4](rules/2-4-use-children-helper.md) | Use children Helper | MEDIUM | Use `children()` helper for safe children access |
| [2-5](rules/2-5-component-composition.md) | Prefer Composition | MEDIUM | Prefer composition and context over prop drilling |
| [2-8](rules/2-8-style-prop-conventions.md) | Style Prop Conventions | MEDIUM | Use object syntax with kebab-case properties for `style` |

### 3. Control Flow (7 rules)

| # | Rule | Priority | Description |
| - | ---- | -------- | ----------- |
| [3-1](rules/3-1-use-show-for-conditionals.md) | Use Show for Conditionals | HIGH | Use `<Show>` for conditional rendering and its function child when callers need a narrowed value |
| [3-2](rules/3-2-use-for-for-lists.md) | Use `For` for Lists | HIGH | Use `<For>` for referentially keyed list rendering |
| [3-7](rules/3-7-use-keyed-for-stateful-children.md) | Use keyed for Stateful Children | HIGH | Add `keyed` when child has internal state and value identity (not just truthiness) matters |
| [3-3](rules/3-3-use-index-for-primitives.md) | Use Index for Primitives | MEDIUM | Use `<Index>` when array index matters more than identity |
| [3-4](rules/3-4-use-switch-match.md) | Use Switch/Match | MEDIUM | Use `<Switch>`/`<Match>` for multiple conditions; narrowed accessors throw once their branch deactivates |
| [3-6](rules/3-6-stable-component-mount.md) | Stable Component Mount | MEDIUM | Avoid rendering the same component in multiple Switch/Show branches |
| [3-5](rules/3-5-provide-fallbacks.md) | Provide Fallbacks | LOW | Always provide `fallback` props for loading states |

### 4. State Management (7 rules)

| # | Rule | Priority | Description |
| - | ---- | -------- | ----------- |
| [4-1](rules/4-1-signals-vs-stores.md) | Signals vs Stores | HIGH | Use signals for primitives, stores for nested objects |
| [4-2](rules/4-2-store-path-updates.md) | Use Store Path Syntax | HIGH | Use path syntax for granular, efficient store updates |
| [4-3](rules/4-3-use-produce-for-mutations.md) | Use produce for Mutations | MEDIUM | Use `produce` for complex mutable-style store updates |
| [4-4](rules/4-4-use-reconcile-for-data.md) | Use reconcile for Server Data | MEDIUM | Use `reconcile` when integrating server/external data |
| [4-5](rules/4-5-use-context-for-global.md) | Use Context for Global State | MEDIUM | Use Context API for cross-component shared state |
| [4-6](rules/4-6-store-functions-with-wrapper.md) | Store Functions with a Wrapper | HIGH | Wrap function values so setStore does not invoke them as updater functions |
| [4-7](rules/4-7-cleanup-at-page-ownership-boundary.md) | Cleanup at the Page Ownership Boundary | HIGH | Use per-page cleanup when multiple routed panes remain mounted; audit every context field when splitting a shared context |

### 5. Refs & DOM (10 rules)

| # | Rule | Priority | Description |
| - | ---- | -------- | ----------- |
| [5-1](rules/5-1-use-refs-correctly.md) | Use Refs Correctly | HIGH | Use callback refs for conditional elements |
| [5-2](rules/5-2-access-dom-in-onmount.md) | Access DOM in onMount | HIGH | Access DOM elements in `onMount`, not during render |
| [5-3](rules/5-3-cleanup-with-oncleanup.md) | Cleanup with onCleanup | HIGH | Always clean up subscriptions and timers |
| [5-5](rules/5-5-avoid-innerhtml.md) | Avoid innerHTML | HIGH | Avoid `innerHTML` to prevent XSS; use JSX or `textContent` |
| [5-7](rules/5-7-web-component-controlled-state.md) | Web Component Controlled State | HIGH | Use `prop:*` properties and `on:wc-*` events for modern custom elements; reserve refs/effects for native or legacy APIs |
| [5-8](rules/5-8-view-transition-wraps-signal-mutation.md) | Wrap Signal Mutation in View Transition | HIGH | Call the Solid setter inside `startViewTransition()` so the browser captures the old DOM before applying the new reactive state |
| [5-9](rules/5-9-two-way-scroll-sync-settle-and-echo.md) | Two-Way Scroll Sync | HIGH | Report only settled scroll positions and skip re-scrolling for your own echo |
| [5-10](rules/5-10-nullable-value-on-progress-and-meter.md) | Possibly Missing progress/meter value | HIGH | `value` is always a property and throws on `undefined`; use `attr:value` |
| [5-4](rules/5-4-use-directives.md) | Use Directives | MEDIUM | Use `use:` directives for reusable element behaviors |
| [5-6](rules/5-6-event-handler-patterns.md) | Event Handler Patterns | MEDIUM | Use `on:`/`oncapture:` namespaces and array handler syntax correctly |

### 6. Performance (6 rules)

| # | Rule | Priority | Description |
| - | ---- | -------- | ----------- |
| [6-1](rules/6-1-avoid-unnecessary-tracking.md) | Avoid Unnecessary Tracking | HIGH | Don't access signals outside reactive contexts |
| [6-2](rules/6-2-use-lazy-components.md) | Use Lazy Components | MEDIUM | Use `lazy()` for code splitting large components |
| [6-3](rules/6-3-use-suspense.md) | Use Suspense | MEDIUM | Use `<Suspense>` for async loading boundaries |
| [6-6](rules/6-6-web-component-css-and-bundle.md) | Web Component CSS and Bundle Strategy | MEDIUM | Import components individually; place `::part()` overrides in a global stylesheet |
| [6-4](rules/6-4-optimize-store-access.md) | Optimize Store Access | LOW | Access only the store properties you need |
| [6-5](rules/6-5-prefer-classlist.md) | Prefer classList | LOW | Use `classList` prop for conditional class toggling |

### 7. Accessibility (4 rules)

| # | Rule | Priority | Description |
| - | ---- | -------- | ----------- |
| [7-1](rules/7-1-semantic-html.md) | Use Semantic HTML | HIGH | Use appropriate semantic HTML elements |
| [7-2](rules/7-2-aria-attributes.md) | Use ARIA Attributes | MEDIUM | Apply appropriate ARIA attributes for custom controls |
| [7-3](rules/7-3-keyboard-navigation.md) | Support Keyboard Navigation | MEDIUM | Ensure all interactive elements are keyboard accessible |
| [7-4](rules/7-4-router-root-link-end.md) | End-Match Root Router Links | HIGH | Add end matching so the root link is not current on every route |

### 8. Testing (12 rules)

| # | Rule | Priority | Description |
| - | ---- | -------- | ----------- |
| [8-1](rules/8-1-configure-vitest-for-solid.md) | Configure Vitest for Solid | CRITICAL | Configure Vitest with Solid-specific resolve conditions and plugin |
| [8-2](rules/8-2-wrap-render-in-arrow.md) | Wrap Render in Arrow Functions | CRITICAL | Always use `render(() => <C />)` not `render(<C />)` |
| [8-3](rules/8-3-test-primitives-in-root.md) | Test Primitives in a Root | HIGH | Wrap signal/effect/memo tests in `createRoot` or `renderHook` |
| [8-4](rules/8-4-handle-async-in-tests.md) | Handle Async in Tests | HIGH | Use `findBy` queries and proper timer config for async behavior |
| [8-5](rules/8-5-use-accessible-queries.md) | Use Accessible Queries | MEDIUM | Prefer role and label queries over test IDs |
| [8-6](rules/8-6-separate-logic-from-ui-tests.md) | Separate Logic from UI Tests | MEDIUM | Test primitives/hooks independently from component rendering |
| [8-7](rules/8-7-browser-mode-for-web-components-and-pwa-apis.md) | Browser Mode for Browser-Dependent Behavior | HIGH | Use a real browser for layout, focus, native APIs, and custom-element behavior jsdom cannot model faithfully |
| [8-8](rules/8-8-testing-headless-ui-libraries.md) | Testing Headless UI Libraries with Non-Standard ARIA | MEDIUM | Headless UI libraries use non-obvious ARIA structures and portals; inspect the actual tree before querying |
| [8-9](rules/8-9-browser-native-api-test-isolation.md) | Browser-Native API Test Isolation | HIGH | Clear IndexedDB and localStorage between tests; close connection before deleteDatabase |
| [8-10](rules/8-10-router-integration-testing.md) | Router Integration Testing | HIGH | Use MemoryRouter `root` prop to provide router context to layout providers |
| [8-11](rules/8-11-tanstack-query-test-setup.md) | TanStack Query Test Setup | HIGH | Create a fresh QueryClient per test with retry and caching disabled |
| [8-12](rules/8-12-deproxy-before-structured-clone.md) | Deproxy Before Structured Clone | HIGH | Remove every reactive proxy before writing data to IndexedDB |

### 9. Web Component Integration (8 rules)

| # | Rule | Priority | Description |
| - | ---- | -------- | ----------- |
| [9-1](rules/9-1-register-custom-elements-early.md) | Register Custom Elements at App Entry | HIGH | Import `/define` side-effects before any SolidJS reactive context |
| [9-2](rules/9-2-defer-slotchange-handlers.md) | Handle slotchange After Slot Assignment | HIGH | `slotchange` is delivered in a microtask; defer only work that needs a later lifecycle or rendering phase |
| [9-3](rules/9-3-decouple-lit-and-solid-reactivity.md) | Treat Custom Element and SolidJS Reactivity as Decoupled | MEDIUM | Use one-way data flow (SolidJS -> attributes/props -> events -> SolidJS); never read custom element internal state from SolidJS reactive contexts |
| [9-4](rules/9-4-thin-web-component-wrappers.md) | Thin Web Component Wrappers | HIGH | Wrappers own labels, layout, type adaptation, and form glue; custom elements own timing and native sync |
| [9-5](rules/9-5-property-vs-attribute-binding.md) | Property vs Attribute Binding | HIGH | Dynamic props on custom elements are already properties; use `prop:*` for intent and `attr:*` for `data-*`, ID-reference ARIA, and CSS-visible attributes |
| [9-6](rules/9-6-register-custom-fields-with-form-libraries.md) | Register Custom Fields with Form Libraries | HIGH | Ensure property-bound custom fields enter lazy form-library registries |
| [9-7](rules/9-7-store-state-for-web-component-heavy-forms.md) | Store State for Web-Component-Heavy Forms | MEDIUM | Prefer a Solid store when custom elements already own field interaction |
| [9-8](rules/9-8-wrapper-signal-for-controlled-only-wc.md) | Wrapper Signal for Controlled-Only WC | HIGH | When a WC has no `defaultValue`, use `createSignal` in the wrapper to own the uncontrolled → controlled bridge |

## Task-Based Rule Selection

### Writing New Components

Load these rules when creating new Solid.js components:

| Rule | Why |
| ---- | --- |
| [1-1](rules/1-1-use-signals-correctly.md) | Ensure signals are called as functions |
| [2-1](rules/2-1-never-destructure-props.md) | Prevent reactivity breakage |
| [2-6](rules/2-6-components-return-once.md) | No early returns; use control flow in JSX |
| [2-9](rules/2-9-never-call-components-as-functions.md) | Never call components as plain functions |
| [2-2](rules/2-2-use-merge-props.md) | Handle default props correctly |
| [2-3](rules/2-3-use-split-props.md) | Separate local and forwarded props |
| [3-1](rules/3-1-use-show-for-conditionals.md) | Proper conditional rendering |
| [3-7](rules/3-7-use-keyed-for-stateful-children.md) | `keyed` for forms and stateful children |
| [3-2](rules/3-2-use-for-for-lists.md) | Efficient list rendering |
| [5-3](rules/5-3-cleanup-with-oncleanup.md) | Prevent memory leaks |

### Web Component Integration

Load these rules when integrating Lit or other custom elements with SolidJS:

| Rule | Why |
| ---- | --- |
| [9-1](rules/9-1-register-custom-elements-early.md) | Register before any SolidJS context mounts |
| [9-2](rules/9-2-defer-slotchange-handlers.md) | Handle assigned nodes after the browser delivers `slotchange` |
| [9-3](rules/9-3-decouple-lit-and-solid-reactivity.md) | One-way data flow design |
| [9-4](rules/9-4-thin-web-component-wrappers.md) | Keep wrappers focused on app concerns |
| [9-5](rules/9-5-property-vs-attribute-binding.md) | `prop:*` for properties, `attr:*` for attributes CSS or ARIA must see |
| [9-6](rules/9-6-register-custom-fields-with-form-libraries.md) | Property-bound fields in form-library registries |
| [9-7](rules/9-7-store-state-for-web-component-heavy-forms.md) | Store state for custom-element-heavy forms |
| [5-6](rules/5-6-event-handler-patterns.md) | Use `on:` namespace for custom element events |

### Code Review

Focus on these rules during code review:

| Priority | Rules |
| -------- | ----- |
| CRITICAL | [1-1](rules/1-1-use-signals-correctly.md), [2-1](rules/2-1-never-destructure-props.md), [2-6](rules/2-6-components-return-once.md), [2-9](rules/2-9-never-call-components-as-functions.md) |
| HIGH | [1-2](rules/1-2-use-memo-for-derived.md), [1-3](rules/1-3-effects-for-side-effects.md), [1-7](rules/1-7-no-primitives-in-reactive-contexts.md), [2-7](rules/2-7-no-react-specific-props.md), [5-2](rules/5-2-access-dom-in-onmount.md), [5-3](rules/5-3-cleanup-with-oncleanup.md), [5-5](rules/5-5-avoid-innerhtml.md) |

### Performance Optimization

Load these rules when optimizing performance:

| Rule | Focus |
| ---- | ----- |
| [1-2](rules/1-2-use-memo-for-derived.md) | Prevent unnecessary recomputation |
| [1-6](rules/1-6-batch-signal-updates.md) | Reduce update cycles |
| [4-2](rules/4-2-store-path-updates.md) | Granular store updates |
| [6-1](rules/6-1-avoid-unnecessary-tracking.md) | Prevent unwanted subscriptions |
| [6-2](rules/6-2-use-lazy-components.md) | Code splitting |
| [6-4](rules/6-4-optimize-store-access.md) | Efficient store access |

### State Management

Load these rules when working with application state:

| Rule | Focus |
| ---- | ----- |
| [4-1](rules/4-1-signals-vs-stores.md) | Choose the right primitive |
| [4-2](rules/4-2-store-path-updates.md) | Efficient updates |
| [4-3](rules/4-3-use-produce-for-mutations.md) | Complex mutations |
| [4-4](rules/4-4-use-reconcile-for-data.md) | External data integration |
| [4-5](rules/4-5-use-context-for-global.md) | Cross-component state |
| [4-6](rules/4-6-store-functions-with-wrapper.md) | Function values in stores |
| [4-7](rules/4-7-cleanup-at-page-ownership-boundary.md) | Several mounted panes sharing context |

### Accessibility Audit

Load these rules when auditing accessibility:

| Rule | Focus |
| ---- | ----- |
| [7-1](rules/7-1-semantic-html.md) | Semantic structure |
| [7-2](rules/7-2-aria-attributes.md) | Screen reader support |
| [7-3](rules/7-3-keyboard-navigation.md) | Keyboard users |
| [7-4](rules/7-4-router-root-link-end.md) | Current-page state on router links |

### Writing Tests

Load these rules when writing or reviewing tests:

| Rule | Focus |
| ---- | ----- |
| [8-1](rules/8-1-configure-vitest-for-solid.md) | Correct Vitest configuration |
| [8-2](rules/8-2-wrap-render-in-arrow.md) | Reactive render scope |
| [8-3](rules/8-3-test-primitives-in-root.md) | Reactive ownership for primitives |
| [8-4](rules/8-4-handle-async-in-tests.md) | Async queries and timers |
| [8-5](rules/8-5-use-accessible-queries.md) | Accessible query selection |
| [8-6](rules/8-6-separate-logic-from-ui-tests.md) | Test architecture |
| [8-7](rules/8-7-browser-mode-for-web-components-and-pwa-apis.md) | When to use browser mode vs jsdom |
| [8-8](rules/8-8-testing-headless-ui-libraries.md) | Portals and non-standard ARIA structures |
| [8-9](rules/8-9-browser-native-api-test-isolation.md) | IDB and localStorage cleanup patterns |
| [8-10](rules/8-10-router-integration-testing.md) | MemoryRouter setup for integration tests |
| [8-11](rules/8-11-tanstack-query-test-setup.md) | QueryClient configuration for tests |
| [8-12](rules/8-12-deproxy-before-structured-clone.md) | Store proxies written to IndexedDB |

### Integrating Web Components / Custom Elements

Load these rules when using any custom element library (Shoelace, FAST, Lion, Material Web
Components, etc.) or native browser APIs like `<dialog>` and the Popover API:

| Rule | Why |
| ---- | --- |
| [2-10](rules/2-10-custom-element-typescript-declarations.md) | Declare custom element tags in JSX namespace; type newer HTML attributes and experimental CSS properties |
| [5-6](rules/5-6-event-handler-patterns.md) | Use `on:` for all custom element events; type `CustomEvent` payloads correctly |
| [5-7](rules/5-7-web-component-controlled-state.md) | Prefer declarative `prop:*`/`on:wc-*`; use refs for native or legacy APIs only |
| [6-6](rules/6-6-web-component-css-and-bundle.md) | Per-component imports for tree-shaking; `::part()` overrides in global CSS only |
| [9-8](rules/9-8-wrapper-signal-for-controlled-only-wc.md) | When the WC has no `defaultValue`, own the uncontrolled → controlled bridge with `createSignal` |
| [5-8](rules/5-8-view-transition-wraps-signal-mutation.md) | Keep Solid's DOM update inside the View Transition snapshot callback |
| [5-10](rules/5-10-nullable-value-on-progress-and-meter.md) | `value` on native `<progress>`/`<meter>` throws on `undefined` |

### Carousels and Scroll-Synced Components

Load [5-9](rules/5-9-two-way-scroll-sync-settle-and-echo.md) when an index is both driven into a
scroll container and reported back out of it.

### Migrating From React

Load [signals](rules/1-1-use-signals-correctly.md),
[component execution](rules/2-6-components-return-once.md),
[reactive props](rules/2-1-never-destructure-props.md),
[HTML prop names](rules/2-7-no-react-specific-props.md),
[style syntax](rules/2-8-style-prop-conventions.md),
[control flow](rules/3-1-use-show-for-conditionals.md),
[list rendering](rules/3-2-use-for-for-lists.md), and
[event handlers](rules/5-6-event-handler-patterns.md).

## Tooling

For automated linting alongside these best practices, use
[eslint-plugin-solid](https://github.com/solidjs-community/eslint-plugin-solid). The plugin catches
many of the same issues this skill covers (destructured props, early returns, React-specific props,
innerHTML usage, style prop format, etc.) and provides auto-fixable rules.

## Resources

- [Solid.js Documentation](https://docs.solidjs.com/)

Files in this skill

  • AGENTS.md2.6 KB
  • CHANGELOG.md12.6 KB
  • SKILL.md20.6 KB
  • docs/version-support-plan.md2.1 KB
  • rules/1-1-use-signals-correctly.md2.6 KB
  • rules/1-2-use-memo-for-derived.md3.8 KB
  • rules/1-3-effects-for-side-effects.md4.2 KB
  • rules/1-4-avoid-signal-in-effect.md5.5 KB
  • rules/1-5-use-untrack-when-needed.md4.5 KB
  • rules/1-6-batch-signal-updates.md5.7 KB
  • rules/1-7-no-primitives-in-reactive-contexts.md2.4 KB
  • rules/2-1-never-destructure-props.md3.3 KB
  • rules/2-10-custom-element-typescript-declarations.md6.8 KB
  • rules/2-2-use-merge-props.md3.8 KB
  • rules/2-3-use-split-props.md4.5 KB
  • rules/2-4-use-children-helper.md3.8 KB
  • rules/2-5-component-composition.md4.9 KB
  • rules/2-6-components-return-once.md4.8 KB
  • rules/2-7-no-react-specific-props.md3.6 KB
  • rules/2-8-style-prop-conventions.md5.1 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.