{"_id":"@amdeu/stim","_rev":"4-4ac4759863f3bd07d9950a9e166fbf2d","name":"@amdeu/stim","dist-tags":{"latest":"2.0.5"},"versions":{"2.0.2":{"name":"@amdeu/stim","version":"2.0.2","author":{"name":"Amadeus Kiener"},"license":"MIT","_id":"@amdeu/stim@2.0.2","maintainers":[{"name":"amdeu","email":"amd.kiener@gmail.com"}],"homepage":"https://github.com/amdeu/stim#readme","bugs":{"url":"https://github.com/amdeu/stim/issues"},"dist":{"shasum":"b65f9c0b07b25619a19e491f9830d0d4af99b1a4","tarball":"https://registry.npmjs.org/@amdeu/stim/-/stim-2.0.2.tgz","fileCount":8,"integrity":"sha512-2DanKXTIlp8o8S87LbOazB0Pl68VUsqtBVfxeG5kkX+j+2o+o/SXiw1P9sCdOjvJG1WbY1sQOnE1hm2nnJ0jHA==","signatures":[{"sig":"MEUCIQCl4V/UVdgoJP2mT1o8YRxHG34H38xjp9hve0bRk0W31gIgWvZMwgjiXxMDB3RwlJ7R1gB450H6GeKxa4bHjH7q4fM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":86120},"main":"dist/stim.umd.js","types":"dist/stim.d.ts","module":"dist/stim.js","gitHead":"6520041f7d2f32627cb1129a383d2e5b12f84b8f","scripts":{"test":"jest src/index.test.js","build":"rollup -c","watch":"rollup -wc","release":"rollup -c && npm test && npm publish"},"_npmUser":{"name":"amdeu","email":"amd.kiener@gmail.com"},"repository":{"url":"git+https://amdeu@github.com/amdeu/stim.git","type":"git"},"_npmVersion":"10.8.1","description":"A modest stimulus knock-off","directories":{},"_nodeVersion":"22.4.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^9.14.0","rollup":"^2.79.2","@babel/preset-env":"^7.26.9","rollup-plugin-copy":"^3.5.0","rollup-plugin-terser":"^7.0.2","jest-environment-jsdom":"^29.7.0","@rollup/plugin-node-resolve":"^15.3.0"},"_npmOperationalInternal":{"tmp":"tmp/stim_2.0.2_1762531823360_0.38213353391218496","host":"s3://npm-registry-packages-npm-production"}},"2.0.3":{"name":"@amdeu/stim","version":"2.0.3","author":{"name":"Amadeus Kiener"},"license":"MIT","_id":"@amdeu/stim@2.0.3","maintainers":[{"name":"amdeu","email":"amd.kiener@gmail.com"}],"homepage":"https://github.com/amdeu/stim#readme","bugs":{"url":"https://github.com/amdeu/stim/issues"},"dist":{"shasum":"fc064d0b5ca4369ed400ab5cc13cea78c284ac67","tarball":"https://registry.npmjs.org/@amdeu/stim/-/stim-2.0.3.tgz","fileCount":8,"integrity":"sha512-SSXirkqUPeFuic5VoPonkUVeHJQHkRTxl7TsPMrGNSk01tVXc0mzR2zn7V/HSXtLCTjZRO3cTX5LJkqKfkDO7Q==","signatures":[{"sig":"MEYCIQCggbUwZountQkDt/vKkGc5J/gXBxv7LqDHv/vEIwYdrQIhAOvCmnNJ2aP3eExgqpSgkpOI/xeaxKZ1Vfpw8Ti3TIis","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":86274},"main":"dist/stim.umd.js","types":"dist/stim.d.ts","module":"dist/stim.js","gitHead":"6c2233aa97f98739094ecd2a82fdc0f4d2d76ffe","scripts":{"test":"jest src/index.test.js","build":"rollup -c","watch":"rollup -wc","release":"rollup -c && npm test && npm publish"},"_npmUser":{"name":"amdeu","email":"amd.kiener@gmail.com"},"repository":{"url":"git+https://amdeu@github.com/amdeu/stim.git","type":"git"},"_npmVersion":"10.8.1","description":"A modest stimulus knock-off","directories":{},"_nodeVersion":"22.4.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^9.14.0","rollup":"^2.79.2","@babel/preset-env":"^7.26.9","rollup-plugin-copy":"^3.5.0","rollup-plugin-terser":"^7.0.2","jest-environment-jsdom":"^29.7.0","@rollup/plugin-node-resolve":"^15.3.0"},"_npmOperationalInternal":{"tmp":"tmp/stim_2.0.3_1770120332688_0.5669508663265341","host":"s3://npm-registry-packages-npm-production"}},"2.0.4":{"name":"@amdeu/stim","version":"2.0.4","author":{"name":"Amadeus Kiener"},"license":"MIT","_id":"@amdeu/stim@2.0.4","maintainers":[{"name":"amdeu","email":"amd.kiener@gmail.com"}],"homepage":"https://github.com/amdeu/stim#readme","bugs":{"url":"https://github.com/amdeu/stim/issues"},"dist":{"shasum":"d16e3925bff090491012b4466bf3f289c75ceffe","tarball":"https://registry.npmjs.org/@amdeu/stim/-/stim-2.0.4.tgz","fileCount":8,"integrity":"sha512-KzAvwXX0Yi3FY5VLVTYZC3qSkkUAtRUQLdjThcccrBPtY5Je4p8EYVEUq4oY0dQD3Oa6tXe5ICHsbtKjLed7QQ==","signatures":[{"sig":"MEUCIQD1PRCeJCzMOSVdhEXcrvKq3IBPkcBP9iCL/dc3hVkHVAIgFUXzQyA0BRqBVyUeSpYUi+7DNJJGvp8ZywJF2P28l4s=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":86354},"main":"dist/stim.umd.js","types":"dist/stim.d.ts","module":"dist/stim.js","gitHead":"3939f76bca3e56a02c6701202d56dd7af5ebc7bb","scripts":{"test":"jest src/index.test.js","build":"rollup -c","watch":"rollup -wc","release":"rollup -c && npm test && npm publish"},"_npmUser":{"name":"amdeu","email":"amd.kiener@gmail.com"},"repository":{"url":"git+https://amdeu@github.com/amdeu/stim.git","type":"git"},"_npmVersion":"10.8.1","description":"A modest stimulus knock-off","directories":{},"_nodeVersion":"22.4.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^9.14.0","rollup":"^2.79.2","@babel/preset-env":"^7.26.9","rollup-plugin-copy":"^3.5.0","rollup-plugin-terser":"^7.0.2","jest-environment-jsdom":"^29.7.0","@rollup/plugin-node-resolve":"^15.3.0"},"_npmOperationalInternal":{"tmp":"tmp/stim_2.0.4_1770120785385_0.5263929577159756","host":"s3://npm-registry-packages-npm-production"}},"2.0.5":{"name":"@amdeu/stim","version":"2.0.5","description":"A modest stimulus knock-off","repository":{"type":"git","url":"git+https://amdeu@github.com/amdeu/stim.git"},"author":{"name":"Amadeus Kiener"},"license":"MIT","bugs":{"url":"https://github.com/amdeu/stim/issues"},"homepage":"https://github.com/amdeu/stim#readme","publishConfig":{"access":"public"},"module":"dist/stim.js","main":"dist/stim.umd.js","types":"dist/stim.d.ts","scripts":{"build":"rollup -c","watch":"rollup -wc","test":"jest src/index.test.js","release":"rollup -c && npm test && npm publish"},"devDependencies":{"@babel/preset-env":"^7.26.9","@rollup/plugin-node-resolve":"^15.3.0","eslint":"^9.14.0","jest":"^29.7.0","jest-environment-jsdom":"^29.7.0","rollup":"^2.79.2","rollup-plugin-copy":"^3.5.0","rollup-plugin-terser":"^7.0.2"},"_id":"@amdeu/stim@2.0.5","gitHead":"3939f76bca3e56a02c6701202d56dd7af5ebc7bb","_nodeVersion":"22.4.1","_npmVersion":"10.8.1","dist":{"integrity":"sha512-xMOcz8Nsn/Zv+/uFkoyHWodQmgCYyNoS80i02XpMFMGizozd7y4eq2DIHNtfgoENj9+fLxZ5iBqwnedKZO/dMA==","shasum":"22b78827530b5366ee28cff965bebd3adaf66beb","tarball":"https://registry.npmjs.org/@amdeu/stim/-/stim-2.0.5.tgz","fileCount":8,"unpackedSize":86483,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCWOYpf25LBsXB6PMTe1nOAFNKRc+90e/xEkKNApPQ6uAIhALnrctvlJCxGv6JEOP1a/Lwhoj/GDR7S6xBkkDqjT3Ps"}]},"_npmUser":{"name":"amdeu","email":"amd.kiener@gmail.com"},"directories":{},"maintainers":[{"name":"amdeu","email":"amd.kiener@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/stim_2.0.5_1771406474973_0.3375243800707173"},"_hasShrinkwrap":false}},"time":{"created":"2025-11-07T16:10:23.253Z","modified":"2026-02-18T09:21:15.273Z","2.0.2":"2025-11-07T16:10:23.561Z","2.0.3":"2026-02-03T12:05:32.827Z","2.0.4":"2026-02-03T12:13:05.547Z","2.0.5":"2026-02-18T09:21:15.139Z"},"bugs":{"url":"https://github.com/amdeu/stim/issues"},"author":{"name":"Amadeus Kiener"},"license":"MIT","homepage":"https://github.com/amdeu/stim#readme","repository":{"type":"git","url":"git+https://amdeu@github.com/amdeu/stim.git"},"description":"A modest stimulus knock-off","maintainers":[{"name":"amdeu","email":"amd.kiener@gmail.com"}],"readme":"# Stim\n\nA lightweight, flexible alternative to [Stimulus](https://github.com/hotwired/stimulus) for adding JavaScript behavior to HTML.\n\n![npm bundle size](https://img.shields.io/bundlephobia/minzip/@amdeu/stim@latest)\n![npm version](https://img.shields.io/npm/v/@amdeu/stim)\n\n## Table of Contents\n\n- [Quick Start](#quick-start)\n- [What Problem Does Stim Solve?](#what-problem-does-stim-solve)\n- [Key Features](#key-features)\n- [Controller Example](#controller-example)\n- [Documentation](#documentation)\n\n## Quick Start\n\n```bash\nnpm install @amdeu/stim\n```\n\n```javascript\n// Define a controller\nimport { Controller, stim } from '@amdeu/stim';\n\nclass Dropdown extends Controller {\n  static props = {\n    open: false\n  }\n\n  connected() {\n    this.element.addEventListener('click', () => {\n      this.open = !this.open;\n    })\n  }\n}\n\n// Register and start\nstim.registerController('dropdown', Dropdown);\nstim.connect();\n```\n\n```html\n<!-- Attach to HTML -->\n<div data-controller=\"dropdown\">\n  <ul>\n    <li>Item 1</li>\n    <li>Item 2</li>\n  </ul>\n</div>\n```\n\n## What Problem Does Stim Solve?\n\nStim provides a structured way to define and connect JavaScript behaviors to HTML.\n\nEspecially when dynamically updating the DOM via AJAX or libraries like [HTMX](https://github.com/bigskysoftware/htmx) and [Turbo](https://github.com/hotwired/turbo), it's nice to have HTML elements that automatically adopt JavaScript behaviors, similar to how custom elements work.\n\nStim follows a simple pattern:\n\n1. You create **Controllers** (JavaScript classes)\n2. You declare which **HTML elements** use those controllers by adding `data-controller` attributes\n3. Stim looks for these attributes on existing and dynamically added elements and instantiates the corresponding controllers\n\n### Why Stim over Alternatives?\n\n#### Compared to Custom Elements\n\n- An element can use multiple controllers rather than being limited to just one class\n- No conflicts with built-in properties or future HTML standards\n- Extending standard elements is possible with full browser support without the limitations of the `is` attribute\n- Compose behaviors by injecting controllers into one another\n- Additional features like targets and actions\n\n>Stim can be used supplementary to custom elements, adding reusable behaviors (like scroll reveal, conditional display etc.) to standard elements and custom elements that define the core functionality of a component.\n\n#### Compared to Stimulus\n\n- **Lighter weight**: ~3kb vs ~11kb minified\n- **More flexible connections**: Targets/Actions can connect \"remotely\" to controllers via ID\n- **Dependency injection**: Controllers can inject other controllers they depend on\n- **Props bulk attribute**: Set props in bulk with JSON\n- **Configurable**: Options to disable mutation observers when not needed\n- **More readable attribute syntax**:\n  - `data-filter-list.category-state=\"value\"` instead of `data-filter-list-category-state-value=\"value\"`\n  - `data-target=\"dropdown.item select.option\"` instead of `data-dropdown-target=\"item\" data-select-target=\"option\"`\n\n## Key Features\n\n- **Controllers**: JavaScript classes that add behavior to HTML elements\n- **Prop Binding**: Two-way binding between JavaScript properties and HTML attributes\n- **Targets**: Direct access to related DOM elements\n- **Actions**: Declarative event handling with parameter passing\n- **Controller Injection**: Compose behaviors by injecting controllers into one another\n- **Remote Connections**: Connect Targets/Actions across the DOM without nesting\n- **Lifecycle Methods**: Structured callbacks for initialization and cleanup\n\n## Controller Example\n\nHere's a simple dropdown that shows key Stim features:\n\n```javascript\n// dropdown.js\nimport { Controller } from '@amdeu/stim';\n\nexport default class Dropdown extends Controller {\n  // Define properties that sync with HTML attributes\n  static props = {\n    open: false  // Tracks open state with data-dropdown.open\n  };\n  \n  // Define types of elements that can connect to this controller\n  static targets = ['button', 'menu'];\n  \n  // Called when the controller is connected\n  connected() {\n    // host element is available as this.element\n    this.element.setAttribute('role', 'menu');\n  }\n  \n  // Called when a button target is connected\n  buttonTargetConnected(button) {\n    // Initialize the button's state\n    button.setAttribute('aria-expanded', this.open);\n    \n    // Add click handler directly to the button\n    button.addEventListener('click', () => {\n      this.open = !this.open; // Toggle state\n    });\n  }\n  \n  // Called when a menu target is connected\n  menuTargetConnected(menu) {\n    // Initialize menu visibility based on current state\n    menu.hidden = !this.open;\n  }\n  \n  // Called when the 'open' prop/property changes\n  openPropChanged(oldValue, newValue) {\n    // Update targets when state changes\n    this.buttonTargets.forEach(btn => {\n        btn.setAttribute('aria-expanded', newValue);\n    });\n\n    if (this.menuTarget) {\n        this.menuTarget.hidden = !newValue;\n    }\n  }\n}\n```\n\n```html\n<!-- Connecting a controller and setting props on the host element -->\n<!-- data-dropdown.open=\"true\" sets an initial state different from the default -->\n<div data-controller=\"dropdown\" data-dropdown.open=\"true\">\n  \n  <!-- Target button element - will toggle dropdown when clicked -->\n  <button data-target=\"dropdown.button\">Menu</button>\n  \n  <!-- Target menu element - will be hidden when open=false -->\n  <div data-target=\"dropdown.menu\">\n    <ul>\n      <li><a href=\"#\">Option 1</a></li>\n      <li><a href=\"#\">Option 2</a></li>\n    </ul>\n  </div>\n</div>\n```\n\n## Documentation\n\n- [**Guide**](./docs/guide.md): Detailed explanations of all core concepts\n- [**API Reference**](./docs/api-reference.md): Complete reference for all properties and methods","readmeFilename":"README.md"}