{"id":36750929,"url":"https://github.com/romshark/datapages","last_synced_at":"2026-04-11T17:12:50.371Z","repository":{"id":331860431,"uuid":"1129179137","full_name":"romshark/datapages","owner":"romshark","description":"A Datastar Go web frontend framework","archived":false,"fork":false,"pushed_at":"2026-04-11T16:11:44.000Z","size":1965,"stargazers_count":52,"open_issues_count":3,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-04-11T17:12:21.570Z","etag":null,"topics":["datastar","framework","golang","nats","proof-of-concept","templ"],"latest_commit_sha":null,"homepage":"https://romshark.github.io/datapages/","language":"Go","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/romshark.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-01-06T18:07:15.000Z","updated_at":"2026-04-11T17:10:55.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/romshark/datapages","commit_stats":null,"previous_names":["romshark/datapages"],"tags_count":28,"template":false,"template_full_name":null,"purl":"pkg:github/romshark/datapages","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romshark%2Fdatapages","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romshark%2Fdatapages/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romshark%2Fdatapages/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romshark%2Fdatapages/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/romshark","download_url":"https://codeload.github.com/romshark/datapages/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romshark%2Fdatapages/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31688222,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-11T13:07:20.380Z","status":"ssl_error","status_checked_at":"2026-04-11T13:06:47.903Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5: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":["datastar","framework","golang","nats","proof-of-concept","templ"],"created_at":"2026-01-12T12:44:37.169Z","updated_at":"2026-04-11T17:12:50.355Z","avatar_url":"https://github.com/romshark.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Datapages\n\n[![CI](https://github.com/romshark/datapages/actions/workflows/ci.yml/badge.svg)](https://github.com/romshark/datapages/actions/workflows/ci.yml)\n[![golangci-lint](https://github.com/romshark/datapages/actions/workflows/golangci-lint.yml/badge.svg)](https://github.com/romshark/datapages/actions/workflows/golangci-lint.yml)\n[![Coverage Status](https://coveralls.io/repos/github/romshark/datapages/badge.svg?branch=main)](https://coveralls.io/github/romshark/datapages?branch=main)\n[![Go Report Card](https://goreportcard.com/badge/github.com/romshark/datapages)](https://goreportcard.com/report/github.com/romshark/datapages)\n[![Go Reference](https://pkg.go.dev/badge/github.com/romshark/datapages.svg)](https://pkg.go.dev/github.com/romshark/datapages)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n![Alpha](https://img.shields.io/badge/status-alpha-orange)\n\n\u003e **🧪 Alpha Software:** Datapages is still in early development 🚧.\u003cbr\u003e\n\u003e APIs are subject to change and you may encounter bugs.\n\nA [Templ](https://templ.guide) + Go + [Datastar](https://data-star.dev) web framework\nfor building dynamic, server-rendered web applications in pure Go.\n\n**Focus on your business logic, generate the boilerplate**\nDatapages parses your app source package and generates all the wiring.\nRouting, sessions and authentication, SSE streams, CSRF protection,\ntype-safe URL and action helpers, Prometheus metrics -\nso your application code stays clean and takes full advantage of Go's strong\nstatic typing and high performance.\n\nNo matter whether you're building **real-time collaborative dynamic web app**\nor simple [HTMX](https://htmx.org/)-style websites - Datapages will serve you well.\n\n## Examples\n\n- [`counter`](example/counter/) — Minimal real-time counter. Bare bones starting point.\n- [`fancy-counter`](example/fancy-counter/) — Fancy real-time collaborative counter.\n- [`todolist`](example/todolist/) — Real-time collaborative todo list with per-tab\n  server-side state (Most [Tao](https://data-star.dev/guide/the_tao_of_datastar) conform example).\n- [`calculator`](example/calculator/) — Hybrid calculator app that runs both as\n  a multi-client server and single-client Desktop app.\n- [`classifieds`](example/classifieds/) —\n  Full-featured classifieds marketplace with sessions, auth, Prometheus metrics,\n  Grafana dashboards and load testing.\n- [`tailwindcss`](example/tailwindcss/) —\n  Minimal static page demonstrating Tailwind CSS integration.\n- [`webcomponents`](example/webcomponents/) —\n  Landing page with vanilla and [Lit](https://lit.dev)-based Web Components\n  bundled via esbuild through a custom watcher.\n\n## Getting Started\n\n### Install\n\n```sh\ngo install github.com/romshark/datapages@latest\n```\n\n### Initialize New Project\n\n```sh\ndatapages init\n```\n\n## CLI Commands\n\n| Command             | Description                                                  |\n| ------------------- | ------------------------------------------------------------ |\n| `datapages init`    | Initialize a new project with scaffolding and configuration. |\n| `datapages gen`     | Parse the app model and generate the datapages package.      |\n| `datapages watch`   | Start the live-reloading development server.                 |\n| `datapages lint`    | Validate the app model without generating code.              |\n| `datapages version` | Print CLI version information.                               |\n\n## Configuration\n\nDatapages reads configuration from `datapages.yaml` or `datapages.yml` in the\nmodule root. If both files exist, the CLI treats that as an error.\n\nThe default scaffold created by `datapages init` looks like this:\n\n```yaml\napp: app\ngen:\n  package: datapagesgen\n  prometheus: true\ncmd: cmd/server\nwatch:\n  exclude:\n    - \".git/**\" # git internals\n    - \".*\"      # hidden files/directories\n    - \"*~\"      # editor backup files\n```\n\nOptional sections can be added as needed:\n\n```yaml\nassets:\n  url-prefix: /static/\n  dir: ./app/static/\n```\n\nThese top-level keys are supported:\n\n- `app`: path to the app source package. Default: `app`\n- `gen.package`: path to the generated package. Default: `datapagesgen`\n- `gen.prometheus`: enable Prometheus metric generation. Default: `true`\n- `cmd`: path to the server command package. Default: `cmd/server`\n- `assets`: embedded static asset serving configuration\n- `watch`: development server settings\n\nWhen `assets` is set, both fields are required. `url-prefix` must start and end\nwith `/` and cannot be `/`.\n\nWhen `gen.prometheus` is set to `false`, the generated server code will not\ninclude Prometheus imports, metric variables, or the `WithPrometheus` server\noption. Use `datapages init --prometheus=false` to scaffold a project without\nPrometheus.\n\nThe optional `watch` section configures the development server\n(host, proxy timeout, debounce, TLS, compiler flags, logging, custom watchers,\netc.).\n\n## Specification\n\nSee [SPECIFICATION.md](SPECIFICATION.md) for the full source package specification,\nincluding handler signatures, parameters, return values, events, sessions, and modules.\n\nSee [FAQ.md](FAQ.md) for frequently asked questions.\n\n## Modules\n\nDatapages ships pluggable modules with swappable implementations:\n\n- [`SessionManager[S]`](modules/sessmanager/sessmanager.go)\n  - [`natskv`](https://pkg.go.dev/github.com/romshark/datapages/modules/sessmanager/natskv) - NATS KV store with AES-128-GCM encrypted cookies\n  - [`inmem`](https://pkg.go.dev/github.com/romshark/datapages/modules/sessmanager/inmem) - In-memory sessions (lost on restart; single-instance only)\n- [`MessageBroker`](modules/msgbroker/msgbroker.go)\n  - [`natsjs`](https://pkg.go.dev/github.com/romshark/datapages/modules/msgbroker/natsjs) - NATS JetStream backed message broker\n  - [`inmem`](https://pkg.go.dev/github.com/romshark/datapages/modules/msgbroker/inmem) - In-memory fan-out message broker (single-instance only)\n- [`TokenManager`](modules/csrf/csrf.go)\n  - [`hmac`](https://pkg.go.dev/github.com/romshark/datapages/modules/csrf/hmac) - HMAC-SHA256 with BREACH-resistant masking\n- [`TokenGenerator`](modules/sessmanager/sessmanager.go)\n  - [`sesstokgen`](https://pkg.go.dev/github.com/romshark/datapages/modules/sesstokgen) - Cryptographically random session tokens (256-bit)\n\n## Motivation\n\nThe reason I built Datapages is that the combination of\n[Datastar](https://data-star.dev) + [Go](https://go.dev) +\n[Templ](https://templ.guide) is my preferred way of writing server-centric\nweb applications. But in every project I used this tech stack for I kept\nrepeating the same code patterns and solving the same problems over and over again.\nI realized many developers are repeating the same patterns too and struggle with the\ncommon pitfalls:\n\n- How to handle SSE streams correctly?\n- How to use NATS effectively?\n- How to approach security and authentication?\n- How to configure a convenient hot-reload for development?\n- How to keep the code maintainable over time,\n  especially when you add more developers and/or AI assistants?\n- How to achieve optimal performance and a good UX for endusers?\n\nDatapages allows you to start quickly and jump straight into building your application\nproviding both a [Datastar Tao oriented](https://data-star.dev/guide/the_tao_of_datastar) \ndefault with examples and enough flexibility to go beyond if you need to.\n\n- `datapages lint` can be used in CI/CD workflows for extensive static code analysis.\n- `datapages gen` generates all boilerplate code consistently, runs lint too and\n  guides your AI coding agents.\n- `datapages watch` opens interactive hot-reload environment for fast a feedback loop\n  with error reporting directly in the browser.\n\nThis tooling also allows LLM coding agents to be more effective at using this tech stack,\nby consistently guiding it on to the right path when it drifts.\n\n\n## Who This Is For\n\nDatapages is a good fit if you:\n\n- **Already write your backend in Go** and want to build your web frontend\n  in the same language and toolchain.\n- **Are building a server-rendered application**, where the server owns the data;\n  not a local-first offline-capable SPA.\n- **Already use [Datastar](https://data-star.dev)** and want a Go framework\n  to help you ship faster with less code while preserving maintainability.\n- **Already use [Templ](https://templ.guide)** and want a full framework\n  built around it.\n- **Use [HTMX](https://htmx.org/),\n  [idiomorph](https://htmx.org/extensions/idiomorph/)\n  and [Alpine.js](https://alpinejs.dev/)**, and instead want a single cohesive stack\n  with a smaller bundle size and less spaghetti-code.\n- **Don't want to maintain a separate REST/GraphQL API** just to feed your frontend.\n- **Want to deploy as a single, statically compiled binary** that makes\n  the most of your hardware.\n- **Want to develop hybrid desktop apps** in Go and HTML5 (see\n  [Calculator example](https://github.com/romshark/datapages/tree/main/example/calculator))\n\n## Contributing\n\nSee [CLAUDE.md](CLAUDE.md) for code style, testing\nconventions, commit message format, and project structure.\n\nUse the `example/classifieds/` application as a real-world\ntest fixture when developing Datapages.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fromshark%2Fdatapages","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fromshark%2Fdatapages","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fromshark%2Fdatapages/lists"}