{"id":26569184,"url":"https://github.com/srdjan/gotium.feexweb","last_synced_at":"2026-04-13T16:04:36.742Z","repository":{"id":283746935,"uuid":"952791263","full_name":"srdjan/gotium.FeexWeb","owner":"srdjan","description":"Modern Web Components wrapper for WebJSX and HTMX","archived":false,"fork":false,"pushed_at":"2025-03-21T23:00:59.000Z","size":32,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-21T23:27:53.192Z","etag":null,"topics":["components","htmx","web","webjsx"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/srdjan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-03-21T22:21:45.000Z","updated_at":"2025-03-21T23:13:38.000Z","dependencies_parsed_at":"2025-03-21T23:27:58.002Z","dependency_job_id":"36ba1b78-21c8-4e32-bf95-92b3fafc43e3","html_url":"https://github.com/srdjan/gotium.FeexWeb","commit_stats":null,"previous_names":["srdjan/gotium.fxweb"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/srdjan%2Fgotium.FeexWeb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/srdjan%2Fgotium.FeexWeb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/srdjan%2Fgotium.FeexWeb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/srdjan%2Fgotium.FeexWeb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/srdjan","download_url":"https://codeload.github.com/srdjan/gotium.FeexWeb/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245015169,"owners_count":20547366,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["components","htmx","web","webjsx"],"created_at":"2025-03-22T20:20:42.396Z","updated_at":"2026-04-13T16:04:36.732Z","avatar_url":"https://github.com/srdjan.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FeexVeb - Functional Web Components Library\n\n## What is FeexVeb?\n\nFeexVeb is a minimal functional library for building web applications with JSX and Web Components. It uses HTMX for server-side driven reactivity. This guide explains how to use **FeexVeb** to create powerful web applications that combine client-side state management with server-driven HTML updates.\n\nIt was created during a one-hour vibe coding session 😊 with Claude. Simply amazing what can be accomplished these days in a short time. Kudos to my sidekick 🙌\n\n**This is not going anywhere, just a little play around.**\n**Disclaimer:** It works on my machine :) - no other guarantees\n\n## Getting Started\n\n### Installation\n\n1. Clone the repository\n2. Start the development server:\n\n   ```bash\n   deno task dev\n   ```\n\n3. Open your browser to `http://localhost:8000`\n\n### Demo Features\n\nThe single demo page (`/`) showcases all FeexVeb features:\n\n- **Pure client-side counter** - Simplified API with attributes and computed state\n- **Minimal counter** - Bare minimum code demonstration\n- **Hybrid counter** - Server + client with HTMX integration and optimistic updates\n- **Server-only counter** - Pure HTMX for comparison\n\nAll components use FeexVeb's built-in monospace design system with no custom CSS required.\n\n### Project Structure\n\n- `lib/feexveb.js` - Core library\n- `lib/src/` - Modular implementation files\n  - `lib/src/monospace-styles.js` - Default monospace styling system\n- `examples/` - Example implementations\n- `server/` - Deno HTTP server for examples\n\n## About FeexVeb and HTMX\n\nFeexVeb is a minimal library for building web applications with JSX and Web Components. It provides:\n\n- **Component Creation**: Define custom elements with reactive state\n- **State Management**: Reactive state with `useState` and `useComputed`, powered by Maverick.js Signals\n- **Side Effects**: Manage effects with cleanup functions\n- **HTMX Integration**: Seamless integration with HTMX for server interactions\n- **Monospace Styling**: Default styling based on \"The Monospace Web\" design principles\n\nHTMX is a dependency-free JavaScript library that allows you to access modern browser features directly from HTML, rather than using JavaScript. It extends HTML with attributes like `hx-get`, `hx-post`, and `hx-swap` that allow you to make AJAX requests and update the page dynamically.\n\n## Why Use FeexVeb with HTMX?\n\nFeexVeb and HTMX complement each other perfectly:\n\n- **FeexVeb**: Provides client-side state management and component lifecycle, using a functional approach with custom elements.\n- **HTMX**: Provides HTML-driven server communication and page updates.\n\nTogether, they create a powerful approach that offers:\n\n1. **Progressive enhancement**: Applications work with or without JavaScript\n2. **Reduced JavaScript**: Much less client-side code to maintain\n3. **Component encapsulation**: Clean organization of UI elements\n4. **Server-driven updates**: Server-rendered HTML instead of complex JSON APIs\n5. **Improved performance**: Smaller JS payload, faster loading times\n6. **Simplified mental model**: HTML-driven approach is easier to reason about\n\n## Creating Components\n\nFeexVeb offers two APIs for creating components: a **simplified API** for quick development and an **advanced API** for full control.\n\n### Simplified API (Recommended)\n\nThe simplified API reduces boilerplate and makes state directly accessible:\n\n```javascript\nFeexVeb.component({\n  tag: 'my-counter',\n\n  // Declarative state definition\n  state: {\n    count: 0\n  },\n\n  // Declarative methods with direct state access\n  methods: {\n    increment: (state) =\u003e state.count++\n  },\n\n  // Direct state access in render (no .get() calls needed)\n  render: ({ count, increment }) =\u003e (\n    \u003cdiv\u003e\n      \u003cdiv\u003eCount: {count}\u003c/div\u003e\n      \u003cbutton onclick={increment}\u003eIncrement\u003c/button\u003e\n    \u003c/div\u003e\n  )\n});\n```\n\n### Advanced API (Full Control)\n\nFor complex components requiring full control:\n\n```javascript\nFeexVeb.defineComponent({\n  tag: 'advanced-counter',\n\n  setup: (ctx) =\u003e {\n    const count = FeexVeb.useState(0);\n\n    return {\n      state: { count },\n      methods: {\n        increment: () =\u003e count.set(count.get() + 1)\n      }\n    };\n  },\n\n  render: (ctx) =\u003e (\n    \u003cdiv\u003e\n      \u003cdiv\u003eCount: {ctx.count.get()}\u003c/div\u003e\n      \u003cbutton onclick={ctx.increment}\u003eIncrement\u003c/button\u003e\n    \u003c/div\u003e\n  )\n});\n```\n\n### Simplified API with Computed State and Attributes\n\n```javascript\nFeexVeb.component({\n  tag: 'smart-counter',\n\n  // State with automatic attribute binding\n  state: {\n    count: 0  // Will be overridden by 'initial-count' attribute\n  },\n\n  // Computed state with automatic dependency tracking\n  computed: {\n    isEven: (state) =\u003e state.count % 2 === 0,\n    doubled: (state) =\u003e state.count * 2\n  },\n\n  // Methods with direct state access\n  methods: {\n    increment: (state) =\u003e state.count++,\n    decrement: (state) =\u003e state.count--,\n    reset: (state) =\u003e state.count = 0\n  },\n\n  // Automatic attribute handling with type inference\n  attrs: {\n    'title': { type: 'string', default: 'Smart Counter' },\n    'initial-count': { type: 'number', default: 0 },\n    'step': { type: 'number', default: 1 }\n  },\n\n  // Direct access to all state, computed values, methods, and attributes\n  render: ({ count, isEven, doubled, increment, decrement, reset, title, step }) =\u003e (\n    \u003cdiv class=\"container\"\u003e\n      \u003ch2\u003e{title}\u003c/h2\u003e\n      \u003cdiv class={isEven ? 'even' : 'odd'}\u003eCount: {count}\u003c/div\u003e\n      \u003cdiv\u003eDoubled: {doubled}\u003c/div\u003e\n      \u003cdiv\u003e\n        \u003cbutton onclick={decrement}\u003e-{step}\u003c/button\u003e\n        \u003cbutton onclick={increment}\u003e+{step}\u003c/button\u003e\n        \u003cbutton onclick={reset}\u003eReset\u003c/button\u003e\n      \u003c/div\u003e\n    \u003c/div\u003e\n  )\n});\n```\n\n### Advanced API with Full Control\n\n```javascript\nFeexVeb.defineComponent({\n  tag: 'advanced-counter',\n  shadowMode: 'open',\n  useMonospaceStyles: true,\n\n  setup: (ctx) =\u003e {\n    const count = FeexVeb.useState(0);\n\n    return {\n      state: { count },\n      methods: {\n        increment: () =\u003e count.set(count.get() + 1)\n      }\n    };\n  },\n\n  render: (ctx) =\u003e (\n    \u003cdiv class=\"container\"\u003e\n      \u003ch2\u003eAdvanced Counter\u003c/h2\u003e\n      \u003cdiv\u003eCount: {ctx.count.get()}\u003c/div\u003e\n      \u003cbutton onclick={ctx.increment}\u003eIncrement\u003c/button\u003e\n    \u003c/div\u003e\n  )\n});\n```\n\n### API Comparison\n\n| Feature | Simplified API | Advanced API |\n|---------|---------------|--------------|\n| **Boilerplate** | Minimal | More verbose |\n| **State Access** | Direct (`count`) | Method calls (`ctx.count.get()`) |\n| **State Definition** | Declarative object | Manual `useState()` calls |\n| **Computed State** | Declarative functions | Manual `useComputed()` calls |\n| **Methods** | Direct state access | Context parameter required |\n| **Attributes** | Automatic type inference | Manual attribute handling |\n| **Learning Curve** | Gentle | Steeper |\n| **Use Case** | Most components | Complex components with advanced needs |\n\n### When to Use Each API\n\n**Use Simplified API (`FeexVeb.component`) when:**\n\n- Building most components (recommended default)\n- You want minimal boilerplate\n- State management is straightforward\n- You prefer declarative patterns\n\n**Use Advanced API (`FeexVeb.defineComponent`) when:**\n\n- You need fine-grained control over component lifecycle\n- Complex state initialization is required\n- You're migrating existing components\n- You need advanced effect management\n\n### HTMX Integration (Hybrid Approach)\n\nThe simplified API works seamlessly with HTMX for server-driven updates while maintaining client-side reactivity:\n\n```javascript\nFeexVeb.component({\n  tag: 'hybrid-counter',\n\n  // Minimal client state for optimistic updates and UI feedback\n  state: {\n    isLoading: false,\n    lastAction: '',\n    optimisticCount: null\n  },\n\n  // Computed state for UI feedback\n  computed: {\n    statusMessage: (state) =\u003e {\n      if (state.isLoading) return `${state.lastAction}...`;\n      return 'Ready';\n    }\n  },\n\n  // Client-side methods for optimistic updates\n  methods: {\n    optimisticIncrement: (state) =\u003e {\n      state.isLoading = true;\n      state.lastAction = 'Incrementing';\n      if (state.optimisticCount !== null) {\n        state.optimisticCount++;\n      }\n    },\n\n    onServerResponse: (state) =\u003e {\n      state.isLoading = false;\n      state.optimisticCount = null; // Server response updates actual display\n    }\n  },\n\n  // Custom setup for HTMX event coordination\n  setup: (ctx) =\u003e {\n    const element = ctx.element;\n\n    // Listen for HTMX events to coordinate client-side state\n    const handleBeforeRequest = (event) =\u003e {\n      const url = event.detail.requestConfig.path;\n      if (url.includes('increment')) {\n        ctx.optimisticIncrement();\n      }\n    };\n\n    const handleAfterRequest = () =\u003e {\n      ctx.onServerResponse();\n    };\n\n    element.addEventListener('htmx:beforeRequest', handleBeforeRequest);\n    element.addEventListener('htmx:afterRequest', handleAfterRequest);\n\n    return {\n      effects: [\n        () =\u003e {\n          element.removeEventListener('htmx:beforeRequest', handleBeforeRequest);\n          element.removeEventListener('htmx:afterRequest', handleAfterRequest);\n        }\n      ]\n    };\n  },\n\n  render: ({ statusMessage, isLoading, optimisticCount }) =\u003e (\n    \u003cdiv class=\"hybrid-counter\"\u003e\n      \u003ch3\u003eHybrid Counter (Server + Client)\u003c/h3\u003e\n\n      {/* Server-driven counter value */}\n      \u003cdiv\n        id=\"server-value\"\n        hx-get=\"/api/counter/value\"\n        hx-trigger=\"load\"\n      \u003e\n        Loading...\n      \u003c/div\u003e\n\n      {/* Client-side optimistic preview */}\n      \u003cdiv class=\"optimistic-preview\"\u003e\n        Preview: {optimisticCount !== null ? optimisticCount : 'Synced'}\n        \u003cdiv class=\"status\"\u003e{statusMessage}\u003c/div\u003e\n      \u003c/div\u003e\n\n      {/* HTMX-powered buttons with optimistic updates */}\n      \u003cbutton\n        hx-post=\"/api/counter/increment\"\n        hx-target=\"#server-value\"\n        hx-swap=\"innerHTML\"\n        disabled={isLoading}\n      \u003e\n        Increment (Server)\n      \u003c/button\u003e\n\n      \u003cbutton\n        hx-post=\"/api/counter/reset\"\n        hx-target=\"#server-value\"\n        hx-swap=\"innerHTML\"\n        disabled={isLoading}\n      \u003e\n        Reset (Server)\n      \u003c/button\u003e\n    \u003c/div\u003e\n  )\n});\n```\n\nThis hybrid approach demonstrates:\n\n- **Server as source of truth**: All mutations go through server endpoints\n- **Optimistic updates**: UI updates immediately for better user experience\n- **HTMX integration**: Declarative server communication with `hx-*` attributes\n- **Client-side reactivity**: Loading states and status messages\n- **Event coordination**: HTMX events trigger client-side state updates\n\n## State Management\n\nFeexVeb's state management system is built on top of [Maverick.js Signals](https://github.com/maverick-js/signals), a high-performance reactive signals library. This provides automatic dependency tracking, efficient updates, and excellent performance while maintaining a simple, familiar API.\n\n### Basic State\n\n```javascript\n// Create reactive state\nconst count = FeexVeb.useState(0);\n\n// Read state\nconsole.log(count.get()); // 0\n\n// Update state\ncount.set(5);\ncount.set(prev =\u003e prev + 1); // Function updates\n\n// Subscribe to changes\nconst unsubscribe = count.subscribe((newValue) =\u003e {\n  console.log('Count changed to:', newValue);\n});\n\n// Cleanup\nunsubscribe();\n```\n\n### Computed State\n\n```javascript\nconst firstName = FeexVeb.useState('John');\nconst lastName = FeexVeb.useState('Doe');\n\n// Computed state automatically tracks dependencies\nconst fullName = FeexVeb.useComputed(() =\u003e {\n  return `${firstName.get()} ${lastName.get()}`;\n}, [firstName, lastName]); // Dependencies array is optional with Maverick.js\n\nconsole.log(fullName.get()); // \"John Doe\"\n\nfirstName.set('Jane');\nconsole.log(fullName.get()); // \"Jane Doe\" - automatically updated\n```\n\n### Effects\n\n```javascript\nconst user = FeexVeb.useState(null);\n\n// Effect runs when dependencies change\nconst cleanup = FeexVeb.useEffect(() =\u003e {\n  console.log('User changed:', user.get());\n\n  // Optional cleanup function\n  return () =\u003e {\n    console.log('Cleaning up previous effect');\n  };\n}, [user]);\n\n// Effect with no dependencies (runs once)\nconst onceCleanup = FeexVeb.useEffect(() =\u003e {\n  console.log('This runs once');\n\n  return () =\u003e {\n    console.log('Cleanup on unmount');\n  };\n}, []); // Empty dependencies array\n\n// Manual cleanup\ncleanup();\nonceCleanup();\n```\n\n### State in Components\n\n```javascript\nFeexVeb.component({\n  tag: 'user-profile',\n\n  setup: (ctx) =\u003e {\n    const user = FeexVeb.useState({ name: 'John', age: 30 });\n    const isAdult = FeexVeb.useComputed(() =\u003e user.get().age \u003e= 18, [user]);\n\n    // Effect for side effects\n    const logEffect = FeexVeb.useEffect(() =\u003e {\n      console.log('User updated:', user.get());\n    }, [user]);\n\n    return {\n      state: { user, isAdult },\n      methods: {\n        updateAge: (newAge) =\u003e {\n          user.set(prev =\u003e ({ ...prev, age: newAge }));\n        }\n      },\n      effects: [logEffect] // Cleanup handled automatically\n    };\n  },\n\n  render: (ctx) =\u003e (\n    \u003cdiv\u003e\n      \u003ch2\u003e{ctx.user.get().name}\u003c/h2\u003e\n      \u003cp\u003eAge: {ctx.user.get().age}\u003c/p\u003e\n      \u003cp\u003eStatus: {ctx.isAdult.get() ? 'Adult' : 'Minor'}\u003c/p\u003e\n      \u003cbutton onclick={() =\u003e ctx.updateAge(ctx.user.get().age + 1)}\u003e\n        Birthday\n      \u003c/button\u003e\n    \u003c/div\u003e\n  )\n});\n```\n\n### Benefits of Maverick.js Signals\n\n1. **Automatic Dependency Tracking** - No need to manually specify dependencies in most cases\n2. **High Performance** - Optimized for minimal re-computations and updates\n3. **Memory Efficient** - Automatic cleanup and garbage collection\n4. **Synchronous Updates** - Predictable update timing with `tick()` for batching\n5. **Battle Tested** - Used in production applications and media players\n\nThe state system maintains full backward compatibility with existing FeexVeb components while providing these performance and developer experience improvements under the hood.\n\n## Styling Components\n\nFeexVeb provides a default monospace styling system based on \"The Monospace Web\" design principles. This styling is automatically applied to components that use Shadow DOM.\n\n### Using Default Monospace Styles\n\n```javascript\n// Enable shadow DOM with default monospace styling\nFeexVeb.component({\n  tag: 'styled-component',\n  shadowMode: 'open', // Enable shadow DOM\n  useMonospaceStyles: true, // Apply monospace styling (default is true)\n\n  // Component implementation...\n});\n```\n\n### Disabling Default Styles\n\n```javascript\n// Enable shadow DOM without default styling\nFeexVeb.component({\n  tag: 'unstyled-component',\n  shadowMode: 'open',\n  useMonospaceStyles: false, // Disable default monospace styling\n\n  // Component implementation...\n});\n```\n\n### Accessing Styling Utilities\n\n```javascript\n// Get the monospace CSS as a string\nconst css = FeexVeb.styling.monospaceCss;\n\n// Create a style element with monospace CSS\nconst styleElement = FeexVeb.styling.createMonospaceStyleElement();\n\n// Inject monospace styles into an element or shadow root\nFeexVeb.styling.injectMonospaceStyles(element);\n```\n\n## Design Philosophy\n\nFeexVeb's default styling system is built upon **\"The Monospace Web\"** design principles created by [Oskar Wickström](https://owickstrom.github.io/the-monospace-web/). This design philosophy emphasizes simplicity, readability, and content-focused web experiences through the strategic use of monospace typography and minimal visual design.\n\n### About \"The Monospace Web\"\n\n\"The Monospace Web\" advocates for:\n\n- **Monospace typography** as the foundation for improved readability and consistent visual rhythm\n- **Minimal color schemes** that prioritize content over decoration\n- **Consistent spacing** using systematic measurements\n- **Focus on content** rather than complex visual elements\n- **Accessibility** through high contrast and clear typography\n\n### FeexVeb's Implementation\n\nFeexVeb implements these principles through two main CSS exports:\n\n- **`FeexVeb.styling.monospaceCss`** - Optimized for Shadow DOM components using `:host` selectors\n- **`FeexVeb.styling.monospaceCssForHtml`** - Adapted for regular HTML documents using `body` and element selectors\n\nBoth implementations provide:\n\n```css\n/* Core monospace font stack */\n--mono-font: ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace;\n\n/* Systematic spacing and sizing */\n--mono-spacing-unit: 1rem;\n--mono-line-height: 1.5;\n--mono-max-width: 70ch;\n\n/* Minimal, accessible color palette */\n--mono-text: #222222;\n--mono-bg: #ffffff;\n--mono-link: #0000ee;\n--mono-border: #dddddd;\n```\n\n### Benefits for FeexVeb Applications\n\n1. **Instant Professional Appearance** - Components look polished without custom CSS\n2. **Consistent User Experience** - Unified design language across all components\n3. **Improved Readability** - Monospace fonts enhance text scanning and comprehension\n4. **Accessibility** - High contrast ratios and clear typography\n5. **Responsive Design** - Built-in mobile-first responsive behavior\n6. **Developer Productivity** - Focus on functionality rather than styling decisions\n\n### Customization and Flexibility\n\nWhile FeexVeb defaults to monospace styling, you maintain full control:\n\n```javascript\n// Use default monospace styling\nFeexVeb.component({\n  tag: 'clean-component',\n  shadowMode: 'open',\n  useMonospaceStyles: true, // Default behavior\n  // ...\n});\n\n// Disable for custom styling\nFeexVeb.component({\n  tag: 'custom-component',\n  shadowMode: 'open',\n  useMonospaceStyles: false, // Opt out of defaults\n  // ...\n});\n```\n\nThis approach allows you to leverage the proven design principles of \"The Monospace Web\" while maintaining the flexibility to customize when needed. We're grateful to Oskar Wickström for creating and sharing these thoughtful design principles that make the web more readable and accessible.\n\n## HTMX Events\n\nFeexVeb can listen to HTMX events for enhanced integration:\n\n```javascript\n// Listen for HTMX events\ndocument.body.addEventListener('htmx:afterSwap', (event) =\u003e {\n  console.log('Content swapped', event.detail.elt);\n});\n\n// Custom HTMX event handling in components\nFeexVeb.component({\n  tag: 'data-loader',\n\n  setup: (ctx) =\u003e {\n    const element = ctx.element;\n\n    // Create effect to handle HTMX events\n    const setupHtmxHandlers = () =\u003e {\n      const handleAfterRequest = (event) =\u003e {\n        console.log('Request completed', event.detail);\n      };\n\n      element.addEventListener('htmx:afterRequest', handleAfterRequest);\n\n      // Return cleanup function\n      return () =\u003e {\n        element.removeEventListener('htmx:afterRequest', handleAfterRequest);\n      };\n    };\n\n    return {\n      effects: [setupHtmxHandlers]\n    };\n  },\n\n  render: (ctx) =\u003e (\n    \u003cdiv\u003e\n      \u003cdiv\n        hx-get=\"/api/data\"\n        hx-trigger=\"load\"\n        hx-indicator=\"#loading\"\n      \u003e\n        Loading...\n      \u003c/div\u003e\n      \u003cdiv id=\"loading\" class=\"htmx-indicator\"\u003e\n        Processing...\n      \u003c/div\u003e\n    \u003c/div\u003e\n  )\n});\n```\n\n## Best Practices\n\n1. **Use attributes for configuration**: Make components configurable with attributes.\n2. **Keep local state minimal**: Use server state for shared data.\n3. **Progressive enhancement**: Ensure basic functionality works without JavaScript.\n4. **Use HTMX for server communication**: Let HTMX handle all AJAX requests.\n5. **Use events for cross-component communication**: The event bus can coordinate between components.\n6. **Cache selectors**: Use `document.getElementById` once and store the reference.\n7. **Avoid shadow DOM for HTMX-heavy components**: Shadow DOM can complicate HTMX targeting.\n8. **Process HTMX after DOM updates**: Use `htmx.process` after manual DOM manipulation.\n9. **Use shadow DOM with monospace styling for UI components**: Get consistent, clean styling with minimal effort.\n10. **Disable default styling when needed**: Use `useMonospaceStyles: false` for components that need custom styling.\n\n## Resources\n\n- [HTMX Documentation](https://htmx.org/docs/)\n- [The Monospace Web](https://owickstrom.github.io/the-monospace-web/) - Design principles for the default styling\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsrdjan%2Fgotium.feexweb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsrdjan%2Fgotium.feexweb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsrdjan%2Fgotium.feexweb/lists"}