{"id":28959601,"url":"https://github.com/thednp/framework-starter","last_synced_at":"2025-06-24T00:03:05.894Z","repository":{"id":298663062,"uuid":"1000684622","full_name":"thednp/framework-starter","owner":"thednp","description":"⚛️ A lightweight, reactive TypeScript framework for building dynamic web interfaces.","archived":false,"fork":false,"pushed_at":"2025-06-12T07:18:25.000Z","size":20,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-06-12T08:23:57.929Z","etag":null,"topics":["framework","javascript","signals","typescript"],"latest_commit_sha":null,"homepage":"https://stackblitz.com/fork/github/thednp/framework-starter","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/thednp.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}},"created_at":"2025-06-12T07:01:56.000Z","updated_at":"2025-06-12T07:23:16.000Z","dependencies_parsed_at":"2025-06-12T08:24:18.461Z","dependency_job_id":"52172bed-2de1-4ebb-9169-7c5099681da6","html_url":"https://github.com/thednp/framework-starter","commit_stats":null,"previous_names":["thednp/framework-starter"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/thednp/framework-starter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thednp%2Fframework-starter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thednp%2Fframework-starter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thednp%2Fframework-starter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thednp%2Fframework-starter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thednp","download_url":"https://codeload.github.com/thednp/framework-starter/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thednp%2Fframework-starter/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261577978,"owners_count":23179767,"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":["framework","javascript","signals","typescript"],"created_at":"2025-06-24T00:02:58.043Z","updated_at":"2025-06-24T00:03:05.889Z","avatar_url":"https://github.com/thednp.png","language":"TypeScript","readme":"# ⚛️ Reactive Framework Starter\n\nA lightweight, reactive TypeScript framework for building dynamic web interfaces with a simple signal-based state management system and a flexible DOM creation utility.\n\nWhen creating a new vite project, this should be the JavaScript / TypeScript starter template.\n\n[Try it now!](https://stackblitz.com/fork/github/thednp/framework-starter)\n\n## Features\n\n- **Reactive State Management**: Uses signals (`signal`) and effects (`effect`) for reactive updates.\n- **Type-Safe DOM Creation**: Provides a `createElement` function for creating HTML, SVG, and MathML elements with TypeScript support.\n- **Automatic Cleanup**: Handles cleanup of event listeners and reactive effects.\n- **Namespace Support**: Supports namespaced attributes (e.g., `xlink:href`, `xml:lang`) for SVG and other elements.\n- **Flexible Child Nodes**: Supports strings, numbers, DOM nodes, arrays, and reactive accessors as children.\n\n## Installation\n\nThis framework is not a published package. To use it, follow these ease steps:\n\n1) Clone the project:\n\n```bash\ngit clone https://github.com/thednp/framework-starter.git my-project\n```\n\n2) Install dependencies:\n\n```bash\ncd my-project \u0026\u0026 npm install\n```\n\n3) Run the development server:\n```bash\nnpm run dev\n```\n\n\n## Usage\n\nThe main files of this mini framework are:\n- `src/framework/state.ts`: Core reactive state management.\n- `src/framework/h.ts`: DOM creation and manipulation utilities.\n- `src/framework/ns.ts`: Namespace definitions for SVG and MathML elements.\n\nEnsure you have a TypeScript environment set up. You can include these files in a TypeScript project and compile them with a tool like Vite or `tsc`.\n\n## Usage\n\n### Creating a Signal\n\nUse `signal` to create reactive state:\n\n```ts\nimport { signal } from './framework';\n\nconst [count, setCount] = signal(0);\n```\n* `count` is an accessor function (() =\u003e T) that retrieves the current value.\n* `setCount` is a setter function ((v: T) =\u003e void) that updates the value and notifies observers.\n\n\n### Creating Effects\n\nUse `effect` to run side effects when signals change:\n\n```ts\nimport { signal, effect } from './framework';\n\nconst [count, setCount] = signal(0);\n\neffect(() =\u003e {\n  console.log(`Count is ${count()}`);\n});\n```\n\n\u003e **Note**: `effect` automatically tracks dependencies (signals accessed within it) and re-runs when they change.\n\n\n### Creating DOM Elements\n\nUse `createElement` to build DOM elements with reactive props and children:\n\n```ts\nimport { createElement, signal } from './framework';\n\nconst [count, setCount] = signal(0);\n\nconst button = createElement('button', \n  { \n    class: 'my-button', \n    'data-count': count, \n    onclick: () =\u003e setCount(count() + 1) \n  },\n  () =\u003e `Count is ${count()}`\n);\n```\n\n\u003e **Notes**:\n\u003e * `createElement` supports HTML, SVG, and MathML elements with automatic namespace resolve.\n\u003e * Props can be static values or reactive accessors (e.g., `count`).\n\u003e * Event handlers are attached for props starting with \"on\" (e.g., `onclick`).\n\u003e * Children can be `String`s, `Number`s, DOM `Node`s, `Array`s, or reactive `Accessor`s.\n\n\n## Example Application\n```ts\nimport { signal, createElement, add } from './framework';\n\nfunction Counter() {\n  const [count, setCount] = signal(0);\n  const doubleCount = () =\u003e count() * 2;\n\n  const button1 = createElement('button', \n    { class: 'my-button-1', 'data-count': count, onclick: () =\u003e setCount(count() + 1) },\n    () =\u003e `Count is ${count()}`\n  );\n  const button2 = createElement('button', \n    { class: 'my-button-2', 'data-doublecount': doubleCount, onclick: () =\u003e setCount(count() + 1) },\n    'Double count is ', doubleCount\n  );\n\n  return [button1, button2];\n}\n\nfunction App() {\n  const h1 = createElement('h1', 'Vite + TypeScript');\n  return createElement('div', h1, Counter());\n}\n\nadd(document.getElementById('app')!, App());\n```\n\nThis creates a simple app with a heading and two buttons that share a common `count` state, demonstrating reactivity and component composition.\n\n\n## API Reference\n```ts\nfunction signal\u003cT\u003e(value: T): [Accessor\u003cT\u003e, Setter\u003cT\u003e]\n```\nCreates a reactive `signal` with an `Accessor` and a `Setter`.\n\n```ts\ntype Accessor\u003cT\u003e: () =\u003e T\n```\nAn `Accessor` retrieves the current value.\n\n```ts\ntype Setter\u003cT\u003e: (v: T) =\u003e void\n```\nA `Setter` updates the value and notifies observers.\n\n```ts\nfunction effect\u003cT\u003e(fn: () =\u003e T | void): () =\u003e void\n```\nRuns a function reactively, tracking signal dependencies, with cleanup support.\nReturns a cleanup function to stop the effect.\n\n```ts\nfunction createElement\u003cK extends TagNames\u003e(tagName: K, props?: DOMNodeAttributes | MaybeChildNode, ...children: MaybeChildNode[]): DOMElement\n```\nCreates a DOM element with the specified tag, props, and children.\n* `tagName`: HTML, SVG, or MathML tag name.\n* `props`: Object with attributes, event handlers (on*), or reactive accessors.\n* `children`: `String`s, `Number`s, `Node`s, `Array`s of the other three, or reactive accessors.\n* Supports namespaces for SVG/MathML and attributes like `xlink:href`.\n\n```ts\nfunction add = (parent: ParentNode, child: MaybeChildNode)\n```\nAppends one or more child `Element`s or `String`s to a parent `Node`, handling various child types.\n\n\n## Contributing\nThis is a minimal framework for educational purposes. Contributions are welcome! Potential improvements include:\n* Adding a proper component / templating system.\n* Enhancing cleanup for event listeners.\n* Supporting more advanced reactive patterns (e.g., `memo`, `async`, etc.).\n* Improving TypeScript inference for custom elements.\n\n\n## Credits\nAll credits go to Ryan Carniato and his [video tutorial](https://www.youtube.com/watch?v=0C-y59betmY) and his [example here](https://playground.solidjs.com/anonymous/e89f77f1-19b3-4286-8dff-31902de34bdd).\n\n\n## License\n[MIT](LICENSE License). Feel free to use, modify, and distribute this framework.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthednp%2Fframework-starter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthednp%2Fframework-starter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthednp%2Fframework-starter/lists"}