{"id":15542083,"url":"https://github.com/lifeart/glimmer-next","last_synced_at":"2025-04-10T19:10:40.618Z","repository":{"id":214458869,"uuid":"736550812","full_name":"lifeart/glimmer-next","owner":"lifeart","description":"GXT is `glimmer-vm` runtime alternative, only 7kb gzipped","archived":false,"fork":false,"pushed_at":"2024-05-22T17:42:35.000Z","size":1378,"stargazers_count":25,"open_issues_count":36,"forks_count":3,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-05-23T06:27:31.925Z","etag":null,"topics":["compiler","dom-manipulation","glimmer-js","glimmer-next","glimmer-vm","gxt","handlebars","handlebars-js","reactive-framework","template","ui","vite"],"latest_commit_sha":null,"homepage":"https://g-next.netlify.app","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/lifeart.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":"2023-12-28T07:57:05.000Z","updated_at":"2024-06-13T22:45:47.271Z","dependencies_parsed_at":"2024-04-26T20:48:50.179Z","dependency_job_id":"d6e1fedc-13de-4816-9a5b-0bb9594a17d2","html_url":"https://github.com/lifeart/glimmer-next","commit_stats":null,"previous_names":["lifeart/glimmer-next"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lifeart%2Fglimmer-next","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lifeart%2Fglimmer-next/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lifeart%2Fglimmer-next/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lifeart%2Fglimmer-next/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lifeart","download_url":"https://codeload.github.com/lifeart/glimmer-next/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248279602,"owners_count":21077407,"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":["compiler","dom-manipulation","glimmer-js","glimmer-next","glimmer-vm","gxt","handlebars","handlebars-js","reactive-framework","template","ui","vite"],"created_at":"2024-10-02T12:20:38.255Z","updated_at":"2025-04-10T19:10:40.600Z","avatar_url":"https://github.com/lifeart.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GXT [![Netlify Status](https://api.netlify.com/api/v1/badges/43af359b-56a7-4607-9e01-04ca3a545470/deploy-status)](https://app.netlify.com/sites/g-next/deploys)\n\n\u003cimg align=\"right\" width=\"95\" height=\"95\"\n     alt=\"Philosopher’s stone, logo of PostCSS\"\n     src=\"./public/logo.png\"\u003e\n\n`GXT` is a cutting-edge, compilable runtime environment designed as `glimmer-vm` alternative, showcasing the power and flexibility of modern web component development. This repo includes a live example of how `GXT` can be used in real-world applications, providing developers with a practical and interactive experience. Explore our [sample](https://g-next.netlify.app/) at netlify.\n\n## Benefits\n\n- 🔥 Hot Module Replacement (Reloading)\n- 🌑 Native shadow-dom support\n- ⌛ Async element destructors support\n- 🖥️ Server Side Rendering\n- 💧 Rehydration\n- 🔧 Ember Developer Tools support\n- 🍃 Runtime code tree-shaking\n- 📦 Small Bundle Size\n- ✍️ Typed Templates with Glint\n- 🤝 Ember syntax compatibility\n- 🚀 40% performance improvement compared to GlimmerVM\n- 💾 2x less memory usage compared to GlimmerVM\n- 🧹 Template linting support via Ember Template Lint\n- ⚛️ Built-in reactivity system\n\n## Development tools for VS Code\n\n- [Language Server](https://marketplace.visualstudio.com/items?itemName=lifeart.vscode-ember-unstable)\n- [Template Syntax](https://marketplace.visualstudio.com/items?itemName=lifeart.vscode-glimmer-syntax)\n- [Templates Type checking](https://marketplace.visualstudio.com/items?itemName=typed-ember.glint-vscode)\n\n## Quick Links\n\n- Related issue: [glimmer-vm/issues/1540](https://github.com/glimmerjs/glimmer-vm/issues/1540)\n- Related PR: [glimmer-vm/pull/1541](https://github.com/glimmerjs/glimmer-vm/pull/1541)\n- Sample App: [js-framework-benchmark](https://github.com/krausest/js-framework-benchmark/tree/master/frameworks/keyed/gxt)\n\n## Component sample\n\nBased on [template imports RFC](https://rfcs.emberjs.com/id/0779-first-class-component-templates/)\n\n```gjs\nimport { RemoveIcon } from \"./RemoveIcon.gts\";\nimport type { Item } from \"@/utils/data\";\nimport { type Cell, cellFor, Component } from \"@lifeart/gxt\";\n\ntype RowArgs = {\n  Args: {\n    item: Item;\n    selectedCell: Cell\u003cnumber\u003e;\n    onRemove: (item: Item) =\u003e void;\n  };\n};\n\nexport class Row extends Component\u003cRowArgs\u003e {\n  get labelCell() {\n    return cellFor(this.args.item, \"label\");\n  }\n  get id() {\n    return this.args.item.id;\n  }\n  get selected() {\n    return this.args.selectedCell.value;\n  }\n  set selected(value: number) {\n    this.args.selectedCell.value = value;\n  }\n  get isSelected() {\n    return this.selected === this.id;\n  }\n  get className() {\n    return this.isSelected ? \"danger\" : \"\";\n  }\n  onClick = () =\u003e {\n    this.selected = this.isSelected ? 0 : this.id;\n  };\n  onClickRemove = (e: Event) =\u003e {\n    this.args.onRemove(this.args.item);\n  };\n  \u003ctemplate\u003e\n    \u003ctr class={{this.className}}\u003e\n      \u003ctd class=\"col-md-1\"\u003e{{this.id}}\u003c/td\u003e\n      \u003ctd class=\"col-md-4\"\u003e\n        \u003ca {{on \"click\" this.onClick}} data-test-select\u003e{{this.labelCell}}\u003c/a\u003e\n      \u003c/td\u003e\n      \u003ctd class=\"col-md-1\"\u003e\n        \u003ca {{on \"click\" this.onClickRemove}} data-test-remove\u003e\n          \u003cRemoveIcon /\u003e\n        \u003c/a\u003e\n      \u003c/td\u003e\n      \u003ctd class=\"col-md-6\"\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/template\u003e\n}\n```\n\n## Key Features\n\n### Simple and Expressive Component Model\n\n- \u003cb\u003eComponent as Functions:\u003c/b\u003e Every component in gNext is a function, executed only once for efficiency and better performance.\n- \u003cb\u003eClass based components:\u003c/b\u003e Class based components are supported as well.\n- \u003cb\u003eBasic Glint Support:\u003c/b\u003e Integration with Glint for improved TypeScript support and developer experience.\n- \u003cb\u003eComprehensive Slot Support:\u003c/b\u003e Full support for different kinds of slots, including {{yield}}, enhancing the flexibility in component composition.\n- \u003cb\u003eModifiers and Helpers APIs:\u003c/b\u003e\n  Modifiers for element-specific logic.\n  Helpers for reusable logic across components.\n- \u003cb\u003eTemplate Imports:\u003c/b\u003e Import templates from other files, enabling better code organization and reusability.\n- \u003cb\u003eTemplate Compilation:\u003c/b\u003e Compile templates to JavaScript functions for improved performance and efficiency.\n- \u003cb\u003eOpcodes tree-shaking:\u003c/b\u003e Opcodes tree-shaking for smaller bundle size. We don't include unused DOM and component, flow-control opcodes in the bundle.\n\n### Reactive Primitives\n\n- \u003cb\u003eMutable State with `cell\u003cT\u003e`:\u003c/b\u003e Use cell\u003cT\u003e for creating reactive, mutable states. Updating and accessing cell values is straightforward and efficient.\n- \u003cb\u003eDerived State with `formula`:\u003c/b\u003e Create derived states that automatically update when dependencies change, ensuring reactive and responsive UIs.\n- \u003cb\u003eSupport for destructors:\u003c/b\u003e Enables clean-up and resource management, preventing memory leaks.\n\n## Benefits and Use Cases\n\n\u003cb\u003egNext\u003c/b\u003e serves as a powerful tool for web developers looking to harness the capabilities of Glimmer-VM in a real-world setting. Its benefits and use cases include:\n\n- \u003cb\u003eEfficient DOM Rendering:\u003c/b\u003e Experience fast and efficient DOM updates and rendering, crucial for high-performance web applications.\n- \u003cb\u003eReactive State Management:\u003c/b\u003e Manage component states reactively, ensuring UIs are always up-to-date with the underlying data.\n- \u003cb\u003eEnhanced Developer Experience:\u003c/b\u003e Enjoy a seamless development experience with features like TypeScript support, comprehensive API documentation, and easy-to-understand examples.\n- \u003cb\u003eFlexible Component Composition:\u003c/b\u003e Leverage advanced component composition techniques to build complex UIs with ease.\n- \u003cb\u003eResource Management:\u003c/b\u003e Efficiently manage resources with destructors, preventing common issues like memory leaks.\n\n\u003cb\u003egNext\u003c/b\u003e is not just a library; it's a gateway to building modern, efficient, and reactive web applications using Glimmer-VM. Whether you are building dynamic user interfaces, complex single-page applications, or just experimenting with new front-end technologies, gNext provides the tools and capabilities to bring your ideas to life.\n\nExplore \u003cb\u003egNext\u003c/b\u003e and elevate your web development experience!\n\n### Notes\n\n#\n\n- modifiers API:\n\n```js\nfunction modifier(element: Element, ...args: Args) {\n    return () =\u003e {\n        // destructor\n    }\n}\n```\n\n- helpers API:\n\n```js\nfunction helper(...args: Args): string | boolean | number | null {\n  // helper logic\n  return 3 + 2;\n}\n```\n\n### Reactive primitives\n\n- `@tracked` - decorator to mark class property as reactive primitive. It's autotrack dependencies and update when any of them changed. Note, to use it you need to add `import 'decorator-transforms/globals';` in top-level file.\n\n- `cell\u003cT\u003e(value)` - reactive primitive, for mutable state. We could update cel calling `cell.update(value)`, to get cell value we could use `cell.value`.\n- `formula(fn: () =\u003e unknown)` - reactive primitive, for derived state.\n\n`formula` could be used to create derived state from `Cell`'s. It's autotrack dependencies and update when any of them changed.\n\n`scope` function is used to suspend `ts` error about unused variables. It's not required for runtime, but required for `ts` compilation.\n\n`destructors` supported.\n\n```ts\nimport { registerDestructor, hbs, scope } from \"@lifeart/gxt\";\n\nexport function Icon() {\n  registerDestructor(this, () =\u003e {\n    console.log(\"destructor\");\n  });\n\n  return hbs`\u003ci class=\"glyphicon glyphicon-remove\"\u003e\u003c/i\u003e`;\n}\n```\n\n### Setup\n\nStart project from this template: https://github.com/lifeart/template-gxt\n\nor\n\n```\npnpm create vite my-app --template vanilla-ts\npnpm install @lifeart/gxt\n```\n\nEdit `vite.config.mts` to import compiler:\n\n```js\nimport { defineConfig } from \"vite\";\nimport { compiler } from \"@lifeart/gxt/compiler\";\n\nexport default defineConfig(({ mode }) =\u003e ({\n  plugins: [compiler(mode)],\n}));\n```\n\nTo render root component, use `renderComponent` function.\n\n```js\nimport { renderComponent } from \"@lifeart/gxt\";\nimport App from \"./App.gts\";\n\nconst Instance = renderComponent(\n  App, {\n    // application arguments\n    args: {\n      name: 'My App'\n    },\n    // render target (append to)\n    element: document.getElementById(\"app\"),\n  }\n);\n```\n\nTo destroy component, use `destroyElement` function.\n\n```js\nimport { destroyElement } from \"@lifeart/gxt\";\n\ndestroyElement(Instance);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flifeart%2Fglimmer-next","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flifeart%2Fglimmer-next","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flifeart%2Fglimmer-next/lists"}