{
  "id": "2e8897f852e77df49368988e",
  "source": "solid:signals",
  "type": "github-document",
  "title": "use",
  "content": "---\ntitle: 'use:*'\norder: 5\nuse_cases: \u003e-\n  complex dom interactions, tooltips, form handling, two-way data binding,\n  reusable element behaviors, custom input components\ntags:\n  - directives\n  - dom\n  - forms\n  - bindings\n  - components\n  - typescript\nversion: '1.0'\ndescription: \u003e-\n  Create custom directives in SolidJS to attach reusable behaviors to DOM\n  elements. Perfect for tooltips, form handling, and two-way data binding.\n---\n\nCustom directives attach reusable behavior to DOM elements, acting as syntactic sugar over `ref`. They’re ideal for complex DOM interactions like scrolling, tooltips, or form handling, which are cumbersome to repeat in JSX.\n\nA directive is a function with the following signature\n\n```ts\nfunction directive(element: HTMLElement, accessor: Accessor\u003cany\u003e): void;\n```\n\nDirective functions are called at render time but before being added to the DOM. You can do whatever you'd like in them including create signals, effects, register clean-up etc.\n\n## Example\n\nA `model` directive for two-way data binding\n\n```tsx\nimport type { Accessor, Signal } from \"solid-js\";\n\nfunction model(element: HTMLInputElement, value: Accessor\u003cSignal\u003cstring\u003e\u003e) {\n\tconst [field, setField] = value();\n\tcreateRenderEffect(() =\u003e (element.value = field()));\n\telement.addEventListener(\"input\", ({ target }) =\u003e setField(target.value));\n}\n\nconst [name, setName] = createSignal(\"\");\n\n\u003cinput type=\"text\" use:model={[name, setName]} /\u003e;\n```\n\n## TypeScript Support\n\nTo type custom directives, extend the `DirectiveFunctions` interface\n\n```ts\ndeclare module \"solid-js\" {\n\tnamespace JSX {\n\t\tinterface DirectiveFunctions {\n\t\t\tmodel: typeof model;\n\t\t}\n\t}\n}\n```\n\nIf you just want to constrain the second argument to the directive function, you can extend the older `Directives` interface\n\n```tsx\ndeclare module \"solid-js\" {\n\tnamespace JSX {\n\t\tinterface Directives {\n\t\t\tmodel: Signal\u003cstring\u003e;\n\t\t}\n\t}\n}\n```\n\n## Avoiding Tree-Shaking\n\nWhen importing a directive `d` from another module and using it only as `use:d`, TypeScript (via [babel-preset-typescript](https://babeljs.io/docs/babel-preset-typescript)) may remove the import, as it doesn’t recognize `use:d` as a reference to `d`.\nTo prevent this:\n\n1. Use the `onlyRemoveTypeImports: true` option in `babel-preset-typescript`. For `vite-plugin-solid`, add this to `vite.config.ts`\n\n\t```ts\n\timport solidPlugin from \"vite-plugin-solid\";\n\n\texport default {\n\t\tplugins: [\n\t\t\tsolidPlugin({\n\t\t\t\ttypescript: { onlyRemoveTypeImports: true }\n\t\t\t})\n\t\t],\n   };\n   ```\n\n   Note: This requires consistent use of `export type` and `import type` in your codebase to avoid issues.\n\n2. Add a fake access like `false \u0026\u0026 d;` in the module\n\n\t```tsx\n\timport { model } from \"./directives\";\n\tfalse \u0026\u0026 model; // Prevents tree-shaking\n\t\u003cinput type=\"text\" use:model={[name, setName]} /\u003e;\n\t```\n\n   This is removed by bundlers like Terser, unlike a plain `model;` which may remain in the bundle.\n\n:::caution[Limitations]\nDirectives only work with native HTML elements (HTML/SVG/MathML/Custom Elements).\nDirectives are not forwarded and **won't work in user defined components**, such as `\u003cMyComponent use:myinput={[..]}/\u003e` [see also](https://github.com/solidjs/solid/discussions/722)\n:::",
  "url": "https://github.com/solidjs/solid-docs/blob/HEAD/src/routes/reference/jsx-attributes/use.mdx",
  "metadata": {
    "path": "src/routes/reference/jsx-attributes/use.mdx",
    "repo": "solidjs/solid-docs",
    "repo_url": "https://github.com/solidjs/solid-docs.git",
    "size": 3210,
    "source_type": "github"
  },
  "hash": "09085ac84dee4f7f8262d36d216247739aab11a74e9290a46e8e3762db4bd6b9",
  "timestamp": "2026-02-23T11:43:00.18963652+01:00"
}