{"id":31916962,"url":"https://github.com/srdjan/ui-lib","last_synced_at":"2026-04-10T06:47:57.733Z","repository":{"id":311579168,"uuid":"1043986503","full_name":"srdjan/ui-lib","owner":"srdjan","description":"ui-lib is an ultra-lightweight, type-safe SSR component library with DOM-native state management, HTMX inside and hybrid reactivity. Built with ❤️ for the modern web.","archived":false,"fork":false,"pushed_at":"2025-10-12T14:51:45.000Z","size":3639,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-13T18:21:43.871Z","etag":null,"topics":["css","frontend","html","htmx","javascript","javascript-weekly","react-status","ssr","typescript","ui","web"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-08-25T02:42:04.000Z","updated_at":"2025-10-12T14:51:48.000Z","dependencies_parsed_at":"2025-08-25T11:09:16.572Z","dependency_job_id":"6102f68e-1596-45e4-a3b7-fcc45dfdf1ff","html_url":"https://github.com/srdjan/ui-lib","commit_stats":null,"previous_names":["srdjan/funcwc","srdjan/ui-lib"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/srdjan/ui-lib","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/srdjan%2Fui-lib","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/srdjan%2Fui-lib/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/srdjan%2Fui-lib/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/srdjan%2Fui-lib/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/srdjan","download_url":"https://codeload.github.com/srdjan/ui-lib/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/srdjan%2Fui-lib/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279016939,"owners_count":26085906,"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","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["css","frontend","html","htmx","javascript","javascript-weekly","react-status","ssr","typescript","ui","web"],"created_at":"2025-10-13T20:16:20.289Z","updated_at":"2025-10-13T20:16:25.761Z","avatar_url":"https://github.com/srdjan.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ui-lib\n\nUltra-lightweight, type-safe SSR components with DOM-native state management and\nhybrid reactivity.\n\n## Features\n\n- 🌐 SSR-first, JSX-always rendering\n- 🧭 Light Functional Programming: types-first, pure functions, Result\u003cT,E\u003e, no\n  classes\n- 🧩 DOM-native **state management**: classes, data-* attributes, element content, CSS custom\n  properties\n- 🔒 **Composition-Only Pattern**: Apps compose pre-styled components, enforcing\n  UI consistency\n- 🎨 **Zero Style Conflicts**: No custom CSS in apps\n- 🕵️ **HTMX** encapsulated via component APIs (no hx-* in application code)\n- 📦 Component-colocated API, styles, and reactivity\n- 🔧 Type-safe end-to-end with strict TypeScript\n- 📚 50+ pre-styled components with rich variant APIs; progressive enhancement\n  optional (zero framework runtime)\n\n## Quick Start\n\n### Installation\n\n```bash\n# Local clone (recommended)\ngit clone https://github.com/srdjan/ui-lib.git\ncd ui-lib\n\n# Dev server \u0026 tasks\ndeno task start         # type-check then start the Todo demo\ndeno task serve         # start the Todo demo directly\ndeno task bundle:state  # emits dist/ui-lib-state.js for optional client helpers\n```\n\n### Basic Usage\n\n```tsx\nimport { defineComponent, h, render } from \"ui-lib/mod.ts\";\nimport { Card } from \"ui-lib/components\";\n\n// Application components compose pre-styled library components\ndefineComponent(\"user-card\", {\n  render: ({ name = \"Guest\", role = \"User\" }) =\u003e (\n    \u003ccard variant=\"elevated\" padding=\"lg\"\u003e\n      \u003ch2\u003e{name}\u003c/h2\u003e\n      \u003cp\u003e{role}\u003c/p\u003e\n    \u003c/card\u003e\n  ),\n});\n\n// Use it (JSX + render to produce HTML on the server)\nconst html = render(\u003cuser-card name=\"Alice\" role=\"Admin\" /\u003e);\n```\n\n\u003e **Why Composition-Only?** Applications cannot add custom styles when using\n\u003e `mod.ts`. This enforces UI consistency, reduces code by 94%, and ensures all\n\u003e apps using ui-lib have a uniform look. Custom styling is reserved for library\n\u003e component development (see `lib/internal.ts`).\n\n\u003e Note: In application code, call `render(\u003cComponent /\u003e)` to produce HTML.\n\u003e `renderComponent` is still available for low-level access when needed.\n\n### With Function-Style Props\n\n```tsx\nimport { boolean, defineComponent, h, number, string } from \"ui-lib\";\nimport { Button, Card } from \"ui-lib/components\";\n\ndefineComponent(\"counter\", {\n  render: ({\n    label = string(\"Count\"),\n    value = number(0),\n    disabled = boolean(false),\n  }) =\u003e (\n    \u003ccard variant=\"default\" padding=\"md\"\u003e\n      \u003cspan\u003e{label}: {value}\u003c/span\u003e\n      \u003cbutton variant=\"primary\" size=\"md\" disabled={disabled}\u003e\n        Increment\n      \u003c/button\u003e\n    \u003c/card\u003e\n  ),\n});\n\n// Type-safe usage (JSX-only in app code)\nconst html = \u003ccounter label=\"Items\" value={5} /\u003e;\n```\n\n### Composing Library Components\n\nApplications build UIs by composing pre-styled library components with variants:\n\n```tsx\nimport { Alert, Badge, Button, Card } from \"ui-lib/components\";\n\nconst Page = () =\u003e (\n  \u003c\u003e\n    \u003calert variant=\"success\"\u003e\n      Operation completed!\n    \u003c/alert\u003e\n\n    \u003ccard variant=\"elevated\" padding=\"lg\"\u003e\n      \u003ch2\u003e\n        Welcome \u003cbadge variant=\"primary\"\u003eNew\u003c/badge\u003e\n      \u003c/h2\u003e\n      \u003cp\u003eGet started with ui-lib's 50+ components\u003c/p\u003e\n      \u003cbutton variant=\"primary\" size=\"lg\"\u003e\n        Get Started\n      \u003c/button\u003e\n    \u003c/card\u003e\n  \u003c/\u003e\n);\n```\n\nAll components provide rich variant APIs (primary, secondary, success, danger,\netc.) for customization without CSS.\n\n### Component-Colocated APIs (HTMX Abstracted Away)\n\nComponents define APIs with HTTP method helpers, keeping HTMX completely hidden from application code.\nApplications compose library components with **native spread operators**:\n\n```tsx\nimport { defineComponent, del, h, post } from \"ui-lib/mod.ts\";\n\ndefineComponent(\"todo-item\", {\n  api: {\n    toggle: post(\"/api/todos/:id/toggle\", toggleHandler),\n    remove: del(\"/api/todos/:id\", deleteHandler),\n  },\n  render: ({ todo }, api) =\u003e (\n    \u003citem completed={todo.completed}\u003e\n      \u003cinput type=\"checkbox\" {...api!.toggle(todo.id)} /\u003e\n      \u003cspan\u003e{todo.text}\u003c/span\u003e\n      \u003cbutton {...api!.remove(todo.id)}\u003eDelete\u003c/button\u003e\n    \u003c/item\u003e\n  ),\n});\n```\n\n**Key Benefits:**\n- ✅ **Zero HTMX in app code** - All `hx-*` attributes generated internally\n- ✅ **Zero custom CSS** - Library's `\u003citem\u003e` component provides all styling\n- ✅ **Ergonomic spread syntax** - Use `{...api!.action(id)}` directly in JSX\n- ✅ **Type-safe APIs** - HTTP methods (`post`, `del`, `get`, `patch`, `put`) with route params\n- ✅ **Automatic route registration** - Call `registerComponentApi(\"todo-item\", router)` once\n- ✅ **Children support** - Library components accept custom children with native elements\n\nAvailable HTTP helpers: `get()`, `post()`, `patch()`, `put()`, `del()` (aliased: `remove`, `create`)\n\n## Three-Tier Reactivity\n\n### Tier 1: CSS Property Reactivity\n\nInstant visual updates via CSS custom properties:\n\n```tsx\ndefineComponent(\"theme-toggle\", {\n  reactive: {\n    css: {\n      \"--theme\": \"data-theme\",\n    },\n  },\n  render: () =\u003e `\u003cbutton onclick=\"toggleTheme()\"\u003eToggle Theme\u003c/button\u003e`,\n});\n```\n\n### Tier 2: Pub/Sub State Manager\n\nCross-component state synchronization:\n\n```tsx\ndefineComponent(\"cart\", {\n  reactive: {\n    state: {\n      \"cart-count\": \"data-count\",\n    },\n  },\n  render: () =\u003e `\n    \u003cdiv data-count=\"0\"\u003e\n      Cart Items: \u003cspan x-text=\"count\"\u003e0\u003c/span\u003e\n    \u003c/div\u003e\n  `,\n});\n```\n\n### Tier 3: DOM Event Communication\n\nComponent-to-component messaging:\n\n```tsx\ndefineComponent(\"notification\", {\n  reactive: {\n    on: {\n      \"user:login\": \"handleLogin\",\n    },\n  },\n  render: () =\u003e `\u003cdiv id=\"notification\"\u003e\u003c/div\u003e`,\n});\n```\n\n## Component Library\n\nui-lib includes 50+ production-ready components:\n\n- **Layout**: AppLayout, Navbar, Sidebar, MainContent\n- **Forms**: Input, Select, Textarea, Checkbox, Radio, Switch\n- **Buttons**: Button, ButtonGroup, IconButton\n- **Data**: Table, Card, List, Tree\n- **Feedback**: Alert, Toast, Progress, Skeleton\n- **Overlays**: Modal, Drawer, Popover, Tooltip\n- **Navigation**: Tabs, Breadcrumb, Pagination, Stepper\n- **Display**: Avatar, Badge, Tag, Chip\n\n## Examples\n\nRun the showcase server to see all components in action:\n\n```bash\n# Start the Todo app demo\ndeno task serve\n\n# Open http://localhost:8080\n```\n\nRepo layout (examples)\n\n```\nexamples/\n└── todo-app/\n    ├── server-custom.tsx  # Custom components demo\n    ├── server-library.tsx # Library components demo\n    ├── api/               # Handlers, types, repository\n    └── components/        # SSR components with colocated API/styles/reactivity\n```\n\n## Performance\n\n- **SSR rendering**: ~0.5ms per component\n- **Zero client runtime**: No JavaScript framework needed\n- **Tiny footprint**: \u003c 10KB for optional client enhancements\n- **Streaming**: Built-in support for streaming responses\n\n## Documentation\n\n- [Getting Started](docs/getting-started.md)\n- [Architecture](docs/architecture.md)\n- [Component API](docs/component-api.md)\n- [Examples](docs/examples.md)\n- [Modern CSS Architecture](docs/modern-css-architecture.md)\n\n## Development\n\n```bash\n# Type check\ndeno task check\n\n# Run tests\ndeno task test\n\n# Format code\ndeno task fmt\n\n# Run examples\ndeno task serve\n\n# Build documentation\ndeno task docs\n```\n\n## Philosophy\n\nui-lib reimagines web components by embracing the platform:\n\n1. **State belongs in the DOM** - Not in JavaScript memory\n2. **CSS is the styling language** - Not JavaScript objects (for library\n   components)\n3. **HTML is the structure** - Not virtual DOM trees\n4. **Progressive enhancement** - Not hydration\n5. **Server-first** - Not client-first with SSR bolted on\n6. **Composition over customization** - Apps compose pre-styled components with\n   variants\n\n## Library Development\n\nWhile applications use the composition-only pattern, **library components** have\nfull styling capabilities:\n\n```tsx\n// lib/components/my-component.ts\nimport { css, defineComponent } from \"../../internal.ts\";\n\ndefineComponent(\"my-component\", {\n  styles: css({\n    padding: \"1rem\",\n    backgroundColor: \"var(--surface-bg)\",\n    // Full CSS-in-TS capabilities\n  }),\n  render: ({ variant = \"default\" }) =\u003e (\n    \u003cdiv class={`my-component my-component--${variant}`}\u003e\n      {/* component content */}\n    \u003c/div\u003e\n  ),\n});\n```\n\nLibrary components import from `lib/internal.ts` which provides unrestricted\naccess to:\n\n- Full `defineComponent` with styles\n- CSS-in-TS system (`css`, `createTheme`, `composeStyles`)\n- Theme system and design utilities\n- All internal utilities\n\nSee [Contributing Guide](CONTRIBUTING.md) for details on developing library\ncomponents.\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n\n## Contributing\n\nContributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md)\nfor details.\n\n## Support\n\n- [Documentation](https://ui-lib.dev)\n- [GitHub Issues](https://github.com/yourusername/ui-lib/issues)\n- [Discord Community](https://discord.gg/ui-lib)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsrdjan%2Fui-lib","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsrdjan%2Fui-lib","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsrdjan%2Fui-lib/lists"}