{"id":18321825,"url":"https://github.com/josnin/redgin","last_synced_at":"2026-03-16T06:33:30.484Z","repository":{"id":65580571,"uuid":"561280347","full_name":"josnin/redgin","owner":"josnin","description":"A lightweight (~5.3kb) library for building Web Components","archived":false,"fork":false,"pushed_at":"2024-01-21T13:16:05.000Z","size":264,"stargazers_count":2,"open_issues_count":5,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-19T14:41:20.710Z","etag":null,"topics":["customelements","library","vanilla-javascript","webcomponents"],"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/josnin.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}},"created_at":"2022-11-03T10:58:28.000Z","updated_at":"2024-01-06T09:34:27.000Z","dependencies_parsed_at":null,"dependency_job_id":"fdbb4ef0-f77a-4d2c-9358-74cd6a0a70ba","html_url":"https://github.com/josnin/redgin","commit_stats":{"total_commits":248,"total_committers":1,"mean_commits":248.0,"dds":0.0,"last_synced_commit":"35fdf28681ce2bebfccd6af3cf2e5f06bc38f8ea"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/josnin%2Fredgin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/josnin%2Fredgin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/josnin%2Fredgin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/josnin%2Fredgin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/josnin","download_url":"https://codeload.github.com/josnin/redgin/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247411234,"owners_count":20934650,"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":["customelements","library","vanilla-javascript","webcomponents"],"created_at":"2024-11-05T18:21:56.121Z","updated_at":"2026-03-16T06:33:30.441Z","avatar_url":"https://github.com/josnin.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![NPM](https://nodei.co/npm/redgin.svg?style=flat\u0026data=v,d\u0026color=red)](https://nodei.co/npm/redgin/)\n\n# RedGin\n\nA lightweight (~5.3kb) library that solves the pain points of native Web Components. RedGin offers fine-grained reactivity, surgical updates, and intuitive APIs - making Web Components actually enjoyable to build.\n\n## Why RedGin?\n\nNative Web Components are powerful but come with friction:\n\n| Pain Point | Native Web Components | RedGin |\n|------------|----------------------|--------|\n| **Boilerplate** | Manual lifecycle callbacks, attributeChangedCallback, getters/setters | Zero boilerplate with `getset` and `propReflect` |\n| **Reactivity** | Manual observation with `attributeChangedCallback` | Automatic reactivity with `watch`, `s()`, and fine-grained updates |\n| **Template Updates** | Manual DOM manipulation | Surgical updates - only changed parts re-render |\n| **Attribute Reflection** | Manual sync between properties and attributes | Automatic with `propReflect` |\n| **Event Binding** | `addEventListener` boilerplate | Inline events with `on()` |\n| **Style Sharing** | Duplicated styles per component | Global `shareStyle` injection |\n| **Performance** | Full re-renders on any change | Only changed elements update |\n| **TypeScript** | Complex typing for custom elements | First-class TypeScript support |\n\n## Core Philosophy\n\nRedGin is built around **surgical updates** - only the elements that need to change, change. No virtual DOM, no heavy diffing, just precise, targeted updates to your components.\n\n## Key Features\n\n- **🎯 Surgical Rendering**: Update only what changes - perfect for large lists\n- **📝 Template Literals**: Write components using familiar JS template syntax\n- **⚡️ Fine-grained Reactivity**: Multiple reactivity patterns (`watch`, `s()`, `getset`, `propReflect`)\n- **🔗 Attribute Binding**: Smart `attr()` helper for dynamic attributes\n- **🔄 Property Reflection**: Sync properties with attributes using `propReflect`\n- **📊 Reactive Getters/Setters**: Create reactive state with `getset`\n- **🎨 Style Management**: Global style injection with `shareStyle` and scoped styles with `css`\n- **📘 TypeScript Ready**: Full type safety and IntelliSense\n\n## Installation\n\n### Via npm\n```bash\nnpm i redgin\n```\n\n## Via CDN\n\n```js\n\u003cscript type=\"module\" src=\"https://cdn.jsdelivr.net/npm/redgin@latest/dist/redgin.min.js\"\u003e\u003c/script\u003e\n```\n\n\n## Quick Start\n\n```js\nimport { RedGin, getset, on, html } from 'redgin';\n\nclass Counter extends RedGin {\n  count = getset(0);\n\n  render() {\n    return html`\n      \u003cbutton ${on('click', () =\u003e this.count++)}\u003e\n        Count: ${this.count}\n      \u003c/button\u003e\n    `;\n  }\n}\n\ncustomElements.define('my-counter', Counter);\n```\n\n## API Reference\n\n\n### Core Helpers\n\n| Helper | Purpose | Example |\n| :--- | :--- | :--- |\n| `getset(initial)` | Creates reactive property with getter/setter | `count = getset(0)` |\n| `propReflect(initial)` | Reactive property that reflects to attribute | `theme = propReflect('light')` |\n| `watch(deps, callback)` | Fine-grained control - rerenders when specified dependencies change | `${watch(['count', 'theme'], () =\u003e html`\u003cdiv\u003e...\u003c/div\u003e`)}` |\n| `s(callback)` | Shorthand for reactive value binding | `${s(() =\u003e this.count)}` |\n| `attr(name, callback)` | Surgical attribute binding | `${attr('disabled', () =\u003e !this.editable)}` |\n| `on(event, handler)` | Event listener binding | `${on('click', () =\u003e this.save())}` |\n| `html` | Template literal tag for HTML | `html`\u003cdiv\u003eHello\u003c/div\u003e`` |\n\n### Style Helpers\n\n| Helper | Purpose | Example |\n| :--- | :--- | :--- |\n| `css` | Template literal tag for component-scoped styles | `styles = [css`.card { padding: 1rem; }`]` |\n| `shareStyle(styles)` | Injects global styles across all components | `shareStyle(css:host { --brand: blue; })` |\n\n\n## Lifecycle Methods\n\n* onInit() - After first render\n* onDoUpdate() - After data sync\n* onUpdated() - After every attribute change/requestUpdate\n\n## Style Management Examples\n\n### Global Design System with shareStyle\nimport { RedGin, shareStyle, css, html } from 'redgin';\n\n// Share Bootstrap globally (injected once, used everywhere)\nshareStyle('\u003clink href=\"https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css\" rel=\"stylesheet\"\u003e')\n\n// Share design tokens across all components\n```js\nshareStyle(css`\n  :host {\n    --brand-primary: #007bff;\n    --brand-success: #28a745;\n    --card-shadow: 0 4px 6px rgba(0,0,0,0.1);\n  }\n  \n  .rg-card {\n    border-radius: 8px;\n    box-shadow: var(--card-shadow);\n    transition: transform 0.2s;\n  }\n`);\n\nclass ProductCard extends RedGin {\n  // Component-specific styles (merged with shared styles)\n  styles = [css`\n    .local-price { color: var(--brand-success); font-weight: bold; }\n  `]\n\n  render() {\n    // Bootstrap classes work without local import!\n    return html`\n      \u003cdiv class=\"rg-card p-3\"\u003e\n        \u003cdiv class=\"local-price\"\u003e$120.00\u003c/div\u003e\n        \u003cbutton class=\"btn btn-primary\"\u003eBuy Now\u003c/button\u003e\n      \u003c/div\u003e\n    `;\n  }\n}\n```\n\n## Reactivity Patterns: watch vs s()\n\n### RedGin offers two complementary reactivity patterns:\n\n## s() - Smart Auto-detection\n```js\n// Automatically tracks dependencies\nrender() {\n  return html`\n    \u003cdiv\u003e${s(() =\u003e this.count)}\u003c/div\u003e\n    \u003cdiv\u003e${s(() =\u003e this.theme)}\u003c/div\u003e\n  `;\n}\n```\n\n## watch - Explicit Control\n```js\n// Fine-grained control over dependencies\nrender() {\n  return html`\n    ${watch(['count', 'theme'], () =\u003e html`\n      \u003cdiv class=\"${this.theme}\"\u003e\n        Count: ${this.count}\n      \u003c/div\u003e\n    `)}\n  `;\n}\n```\n\n\n## Examples\n\nCheck out these live examples demonstrating RedGin's capabilities:\n\n### Basic Examples\n* [Simple Counter](https://github.com/josnin/redgin/tree/Dev/samples) - Getting started with RedGin\n* [Two-way Data Binding](https://github.com/josnin/redgin/tree/Dev/samples) - Using getset and events\n* [Todo App](https://github.com/josnin/redgin/tree/Dev/samples) - Classic todo example\n\n\n### Style Examples\n\n* [Bootstrap Integration](https://github.com/josnin/redgin/tree/Dev/samples) - Using shareStyle with CSS frameworks\n* [Design Tokens](https://github.com/josnin/redgin/tree/Dev/samples) - Global theme variables\n* [Scoped Styles](https://github.com/josnin/redgin/tree/Dev/samples) - Component-specific CSS\n\n\n### Advanced Patterns\n* [Surgical List Updates (1,000+ items)](https://github.com/josnin/redgin/tree/Dev/samples) - Only updated rows re-render\n* [E-commerce Application](https://github.com/josnin/redgin/tree/Dev/samples) - Cart, checkout, and async operations\n* [CRM Dashboard](https://github.com/josnin/redgin/tree/Dev/samples) - Multi-view with modals and pipeline\n* [Parent-Child Communication](https://github.com/josnin/redgin/tree/Dev/samples) - Custom events and props\n\n### Integration Examples\n\n* [TypeScript Support](https://github.com/josnin/redgin/tree/Dev/samples) - Full type safety\n* [With Bootstrap](https://github.com/josnin/redgin/tree/Dev/samples) - Using CSS frameworks\n* [Property Reflection](https://github.com/josnin/redgin/tree/Dev/samples) - Syncing props with attributes\n\n## Performance\n\n* Surgical Updates: Only changed elements re-render\n* Bundle Size: ~5.3kb minified + gzipped\n* Memory: Zero virtual DOM overhead\n* Style Injection: Global styles shared once, not duplicated per component\n\n## Contributing\n\nWe welcome contributions!\n```\ngit clone https://github.com/josnin/redgin.git\ncd redgin\nnpm install\nnpm run dev\n```\n\n## Reference\nhttps://web.dev/custom-elements-best-practices/\n\nhttps://web.dev/shadowdom-v1/\n\n\n## Help\n\nNeed help? Open an issue in: [ISSUES](https://github.com/josnin/redgin/issues)\n\n\n## Contributing\nWant to improve and add feature? Fork the repo, add your changes and send a pull request.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjosnin%2Fredgin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjosnin%2Fredgin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjosnin%2Fredgin/lists"}