{"id":41746860,"url":"https://github.com/interaapps/puls","last_synced_at":"2026-01-25T01:04:03.078Z","repository":{"id":276825662,"uuid":"930062086","full_name":"interaapps/puls","owner":"interaapps","description":"(WIP) reactive js/ts library","archived":false,"fork":false,"pushed_at":"2025-12-16T20:16:34.000Z","size":247,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-20T11:02:15.415Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://go.intera.dev/puls-example","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/interaapps.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":null,"dco":null,"cla":null}},"created_at":"2025-02-10T02:03:43.000Z","updated_at":"2025-12-16T20:12:52.000Z","dependencies_parsed_at":"2025-02-10T17:33:43.048Z","dependency_job_id":"cfb54ab8-16a6-4320-8b9a-f5da5657e74d","html_url":"https://github.com/interaapps/puls","commit_stats":null,"previous_names":["interaapps/puls"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/interaapps/puls","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/interaapps%2Fpuls","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/interaapps%2Fpuls/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/interaapps%2Fpuls/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/interaapps%2Fpuls/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/interaapps","download_url":"https://codeload.github.com/interaapps/puls/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/interaapps%2Fpuls/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28740410,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-24T22:12:27.248Z","status":"ssl_error","status_checked_at":"2026-01-24T22:12:10.529Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":[],"created_at":"2026-01-25T01:04:03.017Z","updated_at":"2026-01-25T01:04:03.070Z","avatar_url":"https://github.com/interaapps.png","language":"TypeScript","readme":"# PULS\n```js\nimport { html, appendTo, state } from 'pulsjs'\n\nconst name = state('John')\n\nappendTo(document.body, html`\n    \u003ch1\u003eHello ${name}!\u003c/h1\u003e\n    \n    \u003cinput :bind=${name}\u003e\n`)\n```\nPuls is a reactive web framework that uses the DOM directly.\nIt is inspired by Svelte and Vue. Puls is designed to be simple and fast. It is a great choice for small to medium-sized projects.\n\n**No compiler is required** but if you want, there are .puls component files or JSX support.\n\n## Installation\n```bash\nnpm install pulsjs\n```\n\n### Create with Vite\nCreate a typescript or javascript project with PulsJS and Vite \n```bash\nnpm create pulsjs@latest my-app-name\n```\n\n### ESM import in browser\n```html\n\u003cscript type=\"module\"\u003e\n    import { html, appendTo, state } from 'https://cdn.skypack.dev/pulsjs'\n    ...\n\u003c/script\u003e\n```\n\n\n## Feature overview\n- Puls uses the DOM directly (no virtual DOM)\n- Reactive state\n- Computed values\n- Components\n- Control flow\n- Event handling\n- Bindings\n\n## Hooks (state)\n```js\nimport { state, computed, watch, html, appendTo } from 'pulsjs'\n\nconst name = state('John')\n\nconst computedValue = computed(() =\u003e `I'm happy that you are named ${name.value}`)\n\nwatch([name], () =\u003e {\n    console.log('Name changed')\n})\n\nappendTo(document.body, html`\n    \u003ch1\u003eHello ${name}!\u003c/h1\u003e\n    \n    ${computedValue}\n    \n    \u003cinput :bind=${name}\u003e\n`)\n```\n\n### Deep tracking\n```js\nimport { track, state } from 'pulsjs'\n\nconst hello = state({\n    hello: 'World',\n    world: 'example'\n}, { deep: true })\n\n// only refreshes when hello changes\nwatch([track(() =\u003e hello.value.hello)], () =\u003e {\n    console.log('Hello changed')\n})\n\n```\n\n## Components\n### Functions\n```js\nimport { html } from 'pulsjs'\n\nfunction ExampleComponent({ example }) {\n    return html`\n        \u003cp\u003eExample component ${example}\u003c/p\u003e\n    `\n}\n\nhtml`\n    \u003c${ExampleComponent} example=\"hello world\" /\u003e\n`\n```\n\n#### Function Components Life-Cycle hooks\n\n```ts\nimport {defineEmits, defineProps, defineSlot, html, onMounted} from \"pulsjs\";\n\nfunction ExampleComponent() {\n    const props = defineProps\u003c{\n        example: string;\n    }\u003e()\n    const emit = defineEmits()\n    const slot = defineSlot\u003cNode[]\u003e()\n\n    onMounted(() =\u003e {\n        console.log('Mounted')\n    })\n    \n    onUnmounted(() =\u003e {\n        console.log('Unmounted')\n    })\n\n    return html``\n}\n```\n\n### Class components\n```js\nimport { html } from 'pulsjs'\n\nclass ExampleComponent extends PulsComponent {\n    example = state('val')\n    \n    setup() {\n        console.log('Setup')\n    }\n    \n    render() {\n        return html`\n            \u003cp\u003eExample component ${this.example}\u003c/p\u003e\n        `\n    }\n}\nregisterComponent('example-component', ExampleComponent)\n\n// Typescript\n@CustomElement('example-component')\nexport class ExampleComponent extends PulsComponent {}\n\nconst a = state('test')\nhtml`\n    \u003c${ExampleComponent} example=${a} /\u003e\n`\n```\n\n### Using Web-Components outside of Puls\n```js\nexport class ExampleComponent extends PulsComponent {\n    test = state('hello')\n    exampleObject = state({})\n    // ...\n}\nregisterComponent('example-component', ExampleComponent)\n\ndocument.body.innerHTML = `\n    \u003cexample-component test=\"hello\"\u003e\u003c/example-component\u003e\n    \n    \u003cexample-component :exampleObject=\"{\\\"key\\\": 4}\"\u003e\u003c/example-component\u003e\n`\n```\n\n# Control flow\n```js\nimport { html, appendTo, state, computed } from 'pulsjs'\n\nconst counter = state(1)\n\nhtml`\n    \u003c!-- js ternary operator --\u003e\n    ${computed(() =\u003e \n        counter.value === 1 ? html`\u003cdiv\u003eValue is 1\u003c/div\u003e` :\n        counter.value === 2 ? html`\u003cdiv\u003eValue is 2\u003c/div\u003e` :\n        html`Value is something else`\n    )}\n    \n    \u003c!-- attributes --\u003e\n    \u003cdiv :if=${() =\u003e counter.value === 1}\u003e\n        Value is 1\n    \u003c/div\u003e\n    \u003cdiv :else-if=${() =\u003e counter.value === 1}\u003e\n        Value is 2\n    \u003c/div\u003e\n    \u003cdiv :else\u003e\n        Value is something else\n    \u003c/div\u003e\n    \n    \u003cbutton @click=${() =\u003e counter.value++}\u003eIncrement ${counter}\u003c/button\u003e\n`\n```\n\n\n\n## Extensions\n\n### Puls Component Files (pulsjs-compiler)\nExample `ExampleComponent.puls`\n```svelte\n\u003cscript\u003e\nimport { state } from 'pulsjs'\nconst name = state('John Doe');\n\u003c/script\u003e\n\n\u003ch1\u003e${name}\u003c/h1\u003e\n\u003cinput :bind=${name} /\u003e\n```\n[More Information](https://github.com/interaapps/puls/blob/main/packages/puls-compiler/README.md)\n\n### SCSS\n```bash\nnpm install pulsjs-scss\n```\n\n```js\nimport { PulsComponent, CustomElement, html } from 'pulsjs'\nimport { scss } from 'pulsjs-scss'\n\nexport class ExampleComponent extends PulsComponent {\n    render() {\n        return html`\n            example\n        `\n    }\n    \n    styles() {\n        return scss`\n            example {\n                color: red;\n            }\n        `\n    }\n}\n```\n\n### JSX\n```jsx\nexport function Test() {\n    const name = state('John')\n    return (\n        \u003cdiv\u003e\n            {name}\n            \u003cinput p-bind={name} /\u003e\n            \u003cbutton on:click={() =\u003e name.value = 'test'}\u003eClick me\u003c/button\u003e\n        \u003c/div\u003e\n    )\n}\n```\n\n\n### Router\n```bash\nnpm install pulsjs-router\n```\n```js\nimport { PulsComponent, CustomElement, html } from 'pulsjs'\nimport { Router } from 'pulsjs-router'\n\n\nconst router = new Router([\n    {\n        path: '/',\n        name: 'home',\n        view: () =\u003e html`\n            \u003cdiv\u003e\n                \u003ch1\u003eRouter Works!\u003c/h1\u003e\n            \u003c/div\u003e\n        `\n    },\n    {\n        path: '/test',\n        name: 'test',\n        view: () =\u003e html`\n            \u003cdiv\u003e\n                \u003ch1\u003eRouter page 2!\u003c/h1\u003e\n            \u003c/div\u003e\n        `\n    },\n    {\n        path: '/*',\n        name: '404',\n        view: () =\u003e html`\n            \u003cdiv\u003e\n                \u003ch1\u003e404\u003c/h1\u003e\n            \u003c/div\u003e\n        `\n    }\n    \n    // Also supports nested routes with children and layouting\n])\n\nappendTo(document.body, html`\n    \u003cdiv\u003e\n        ${router.link}\n    \u003c/div\u003e\n    \u003c${router.link} to=${{name: 'home'}}\u003eHome\u003c/${router.link}\u003e\n    \u003c${router.link} to=\"/test\"\u003eTest Page\u003c/${router.link}\u003e\n`)\nrouter.init()\n```\n\n## Contributing\nUse pnpm\n\n### Build\n```bash\npnpm run build\n```\n\n### Test\n```bash\npnpm test\n```","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finteraapps%2Fpuls","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finteraapps%2Fpuls","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finteraapps%2Fpuls/lists"}