{"id":46088034,"url":"https://github.com/praxisjs-org/praxisjs","last_synced_at":"2026-06-07T02:05:56.963Z","repository":{"id":341406616,"uuid":"1170000024","full_name":"praxisjs-org/praxisjs","owner":"praxisjs-org","description":"Signal-driven frontend framework written in TypeScript, combining fine-grained reactivity, class components, and decorators in a complete first-party ecosystem.","archived":false,"fork":false,"pushed_at":"2026-06-03T17:12:58.000Z","size":12620,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-03T19:08:06.723Z","etag":null,"topics":["class-components","decorators","dependency-injection","devtools","frontend-framework","jsx","no-virtual-dom","praxisjs","reactivity","router","signals","state-management","typescript","vite","web-framework"],"latest_commit_sha":null,"homepage":"https://praxisjs.org/","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/praxisjs-org.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":null,"dco":null,"cla":null}},"created_at":"2026-03-01T14:56:46.000Z","updated_at":"2026-06-03T17:11:40.000Z","dependencies_parsed_at":"2026-05-14T17:02:14.921Z","dependency_job_id":null,"html_url":"https://github.com/praxisjs-org/praxisjs","commit_stats":null,"previous_names":["praxisjs-org/praxisjs"],"tags_count":329,"template":false,"template_full_name":null,"purl":"pkg:github/praxisjs-org/praxisjs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/praxisjs-org%2Fpraxisjs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/praxisjs-org%2Fpraxisjs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/praxisjs-org%2Fpraxisjs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/praxisjs-org%2Fpraxisjs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/praxisjs-org","download_url":"https://codeload.github.com/praxisjs-org/praxisjs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/praxisjs-org%2Fpraxisjs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34006056,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-07T02:00:07.652Z","response_time":124,"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":["class-components","decorators","dependency-injection","devtools","frontend-framework","jsx","no-virtual-dom","praxisjs","reactivity","router","signals","state-management","typescript","vite","web-framework"],"created_at":"2026-03-01T17:08:31.358Z","updated_at":"2026-06-07T02:05:56.956Z","avatar_url":"https://github.com/praxisjs-org.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003cimg src=\"assets/logo.svg\" width=\"72\" height=\"72\" alt=\"PraxisJS\" /\u003e\n\n# PraxisJS\n\n**Signal-driven TypeScript frontend framework.**\n\nFine-grained reactivity · Decorator-first class components · Complete ecosystem\n\n[![version](https://img.shields.io/npm/v/@praxisjs/core?label=%40praxisjs%2Fcore\u0026color=38bdf8)](https://www.npmjs.com/package/@praxisjs/core)\n[![coverage](https://codecov.io/gh/praxisjs-org/praxisjs/graph/badge.svg?token=VTZHTEP9QT)](https://codecov.io/gh/praxisjs-org/praxisjs)\n[![license](https://img.shields.io/github/license/praxisjs-org/praxisjs?color=38bdf8)](./LICENSE)\n\n[Docs](https://praxisjs.org) · [Getting Started](https://praxisjs.org/docs/guide/getting-started) · [Changelog](https://praxisjs.org/docs/changelog)\n\n\u003c/div\u003e\n\n---\n\nPraxisJS is a TypeScript frontend framework built around a fine-grained signal engine. Components are plain classes decorated with a rich built-in decorator set — no hooks, no magic strings, no virtual DOM. The first-party ecosystem covers routing, global state, animations, dependency injection, finite state machines, async data, and more.\n\n## Quick look\n\n```tsx\nimport { Component, State, Watch, Resource } from '@praxisjs/decorators'\nimport type { ResourceInstance } from '@praxisjs/decorators'\nimport { StatefulComponent } from '@praxisjs/core'\n\ninterface Post { id: number; title: string }\n\n@Component()\nclass BlogPage extends StatefulComponent {\n  @State() page = 1\n\n  @Resource((self: BlogPage) =\u003e\n    fetch(`/api/posts?page=${self.page}`).then(r =\u003e r.json() as Promise\u003cPost[]\u003e)\n  )\n  posts!: ResourceInstance\u003cPost[]\u003e\n\n  @Watch('page')\n  onPageChange(next: number) {\n    window.scrollTo(0, 0)\n  }\n\n  render() {\n    return (\n      \u003cdiv\u003e\n        {() =\u003e this.posts.pending() \u0026\u0026 \u003cp\u003eLoading…\u003c/p\u003e}\n        {() =\u003e this.posts.data()?.map(p =\u003e \u003ch2\u003e{p.title}\u003c/h2\u003e)}\n        \u003cbutton onClick={() =\u003e this.page++}\u003eNext page\u003c/button\u003e\n      \u003c/div\u003e\n    )\n  }\n}\n```\n\nChanging `this.page` automatically cancels the previous request and starts a new one — no `useEffect`, no manual cleanup.\n\n## Packages\n\n### Foundation\n\n| Package | Version | Description |\n|---|---|---|\n| [`@praxisjs/core`](packages/foundation/core) | `1.7.0` | Signal engine — `signal`, `computed`, `effect`, `batch`, `resource` |\n| [`@praxisjs/decorators`](packages/foundation/decorators) | `1.1.0` | Class component decorators — `@State`, `@Prop`, `@Watch`, `@Emit`, `@Resource`, `@Memo`, … |\n| [`@praxisjs/runtime`](packages/foundation/runtime) | `0.3.0` | DOM renderer, scope system, `Portal` |\n| [`@praxisjs/jsx`](packages/foundation/jsx) | `0.5.0` | JSX runtime (`jsx-runtime`, `jsx-dev-runtime`) |\n| [`@praxisjs/shared`](packages/foundation/shared) | `0.2.0` | Shared types and internal utilities |\n\n```sh\nnpm install @praxisjs/core @praxisjs/decorators @praxisjs/runtime @praxisjs/jsx\n```\n\n### Features\n\n| Package | Version | Description |\n|---|---|---|\n| [`@praxisjs/router`](packages/features/router) | `1.2.0` | Client-side router — `@Router`, `@Route`, `@Lazy`, layouts, navigation guards |\n| [`@praxisjs/store`](packages/features/store) | `1.2.0` | Global reactive state — `@Storable`, `@Store` |\n| [`@praxisjs/di`](packages/features/di) | `1.3.0` | Dependency injection — `Container`, `@Inject`, `@Injectable` |\n| [`@praxisjs/motion`](packages/features/motion) | `1.1.11` | Animations — `@Tween`, `@Spring` |\n| [`@praxisjs/fsm`](packages/features/fsm) | `2.0.0` | Finite state machines — `@StateMachine`, `@Transition` |\n| [`@praxisjs/head`](packages/features/head) | `0.2.0` | Reactive document head — `@Head` for title, meta, og:*, twitter:* |\n| [`@praxisjs/content`](packages/features/content) | `0.1.0` | Markdown content collections — `@Collection`, `@PagedCollection` |\n\n### Utilities\n\n| Package | Version | Description |\n|---|---|---|\n| [`@praxisjs/composables`](packages/utils/composables) | `1.1.2` | Class-based composables — `WindowSize`, `ScrollPosition`, `Focus`, … |\n| [`@praxisjs/concurrent`](packages/utils/concurrent) | `1.2.9` | Async concurrency — `@Task`, `@Queue`, `@Pool` |\n\n### DX\n\n| Package | Version | Description |\n|---|---|---|\n| [`@praxisjs/vite-plugin`](packages/dx/vite-plugin) | `0.1.1` | Vite integration — JSX transform, decorator support, HMR |\n| [`@praxisjs/devtools`](packages/dx/devtools) | `0.2.19` | In-app signal inspector and component profiler |\n| [`@praxisjs/storybook`](packages/dx/storybook) | `0.1.1` | Storybook framework adapter |\n| [`@praxisjs/mcp`](packages/dx/mcp) | `0.1.0` | MCP server for AI assistant integration |\n| [`create-praxisjs`](packages/create-praxisjs) | `0.4.2` | Project scaffolding CLI |\n\n```sh\nnpm create praxisjs@latest\n```\n\n## Monorepo layout\n\n```\npackages/\n  foundation/   core · shared · decorators · jsx · runtime\n  features/     router · store · di · motion · fsm · head · content\n  utils/        composables · concurrent\n  dx/           vite-plugin · devtools · storybook · mcp\n  create-praxisjs/\nplayground/     manual testing app (Vite)\ndocs/           documentation site (Next.js + Fumadocs)\n```\n\n## Development\n\nRequires [pnpm](https://pnpm.io).\n\n```sh\npnpm install\n\n# build everything (required before first run)\npnpm build\n\n# build by layer\npnpm build:foundation\npnpm build:features\npnpm build:utils\npnpm build:dx\n\n# watch mode — rebuild all packages on change\npnpm dev\n\n# playground (hot-reload manual test app)\npnpm --filter playground dev\n\n# tests\npnpm test\npnpm test:watch\npnpm test:coverage\n\n# lint + typecheck\npnpm lint\npnpm lint:fix\npnpm typecheck\n\n# docs dev server\npnpm docs:dev\n```\n\n\u003e After editing a package's source, rebuild it before dependent packages pick up the change:\n\u003e `pnpm --filter @praxisjs/core build`\n\n## Releases\n\nChangesets — pick affected packages, bump type, and summary:\n\n```sh\npnpm changeset          # interactive — create a changeset\npnpm version-packages   # bump versions + sync create-praxisjs templates\npnpm release            # publish to npm\n```\n\n## Contributing\n\nPraxisJS is a personal project built out of curiosity and a desire to explore framework design from scratch. Contributions are welcome — bug reports, ideas, and pull requests. Opening an issue before a large change is appreciated.\n\n## License\n\n[MIT](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpraxisjs-org%2Fpraxisjs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpraxisjs-org%2Fpraxisjs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpraxisjs-org%2Fpraxisjs/lists"}