{"id":19228951,"url":"https://github.com/romshark/templier","last_synced_at":"2026-04-22T00:02:12.962Z","repository":{"id":243719495,"uuid":"813222853","full_name":"romshark/templier","owner":"romshark","description":"A Go Templ web frontend development environment that automatically rebuilds the server and reloads the tab.","archived":false,"fork":false,"pushed_at":"2026-01-14T09:32:10.000Z","size":274,"stargazers_count":105,"open_issues_count":6,"forks_count":4,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-16T23:32:28.464Z","etag":null,"topics":["devenv","frontend","go","golang","reload"],"latest_commit_sha":null,"homepage":"","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":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":"2024-06-10T17:52:11.000Z","updated_at":"2026-01-14T09:31:04.000Z","dependencies_parsed_at":"2025-12-14T15:00:49.561Z","dependency_job_id":null,"html_url":"https://github.com/romshark/templier","commit_stats":null,"previous_names":["romshark/templier"],"tags_count":56,"template":false,"template_full_name":null,"purl":"pkg:github/romshark/templier","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romshark%2Ftemplier","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romshark%2Ftemplier/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romshark%2Ftemplier/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romshark%2Ftemplier/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/romshark","download_url":"https://codeload.github.com/romshark/templier/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romshark%2Ftemplier/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29725352,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-22T19:57:12.410Z","status":"ssl_error","status_checked_at":"2026-02-22T19:54:50.710Z","response_time":110,"last_error":"SSL_read: 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":["devenv","frontend","go","golang","reload"],"created_at":"2024-11-09T15:31:12.291Z","updated_at":"2026-04-11T14:14:43.438Z","avatar_url":"https://github.com/romshark.png","language":"Go","funding_links":[],"categories":["Development Tools"],"sub_categories":[],"readme":"\u003ca href=\"https://goreportcard.com/report/github.com/romshark/templier\"\u003e\n    \u003cimg src=\"https://goreportcard.com/badge/github.com/romshark/templier\" alt=\"GoReportCard\"\u003e\n\u003c/a\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/romshark/templier/5c68f5b74984b6a2c6aec66912f6852819acbf9e/logo_white.svg\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/romshark/templier/5c68f5b74984b6a2c6aec66912f6852819acbf9e/logo_color.svg\" alt=\"Logo\" width=\"400\"\u003e\n\u003c/picture\u003e\n\nTempliér is a Go web frontend development environment for\n[Templ](https://github.com/a-h/templ)\nthat works similarly to templ's native\n[`--watch`](https://templ.guide/developer-tools/live-reload/) mode but provides\nmore functionality and reports errors directly to all open browser tabs ✨.\n\nTempliér allows arbitrary CLI commands to be defined as [custom watchers](#custom-watchers) ✨.\n  - example: [Bundle JavaScript](#custom-watcher-example-javascript-bundler)\n  - example: [Rebuild CSS](#custom-watcher-example-tailwindcss-and-postcss)\n  - example: [Restart on config change](#custom-watcher-example-reload-on-config-change)\n\nTempliér is an integral part of [github.com/romshark/datapages](https://github.com/romshark/datapages/).\n\n## Quick Start\n\nInstall Templiér:\n\n```sh\ngo install github.com/romshark/templier@latest\n```\n\nThen copy [example-config.yml](https://github.com/romshark/templier/blob/main/example-config.yml) to your project source folder as `templier.yml`, adjust it to your needs, and run:\n\n```sh\ntemplier --config ./templier.yml\n```\n\nℹ️ Templiér automatically detects `templier.yml` and `templier.yaml` in the current directory without requiring the explicit `--config` flag.\n\n## How is Templiér different from templ's own watch mode?\n\nAs you may already know, templ supports [live reload](https://templ.guide/commands-and-tools/live-reload)\nout of the box using `templ generate --watch --proxy=\"http://localhost:8080\" --cmd=\"go run .\"`,\nwhich is great, but Templiér provides an even better developer experience:\n\n- 🥶 Templiér doesn't become unresponsive when the Go code fails to compile,\n  instead it prints the compiler error output to the browser tab with ANSI\n  colors preserved and keeps watching.\n  Once you've fixed the Go code, Templiér will reload and work as usual with no intervention.\n  In contrast, templ's watcher needs to be restarted manually.\n- 📁 Templiér watches **all** file changes recursively,\n  recompiles and restarts the server\n  (unless the file matches `app.exclude` or is handled by a [custom watcher](#custom-watchers)).\n  Editing an embedded `.json` file in your app?\n  Updating `go.mod`? Templiér will notice, rebuild, restart, and reload the browser\n  tab for you automatically!\n- 🖥️ Templiér shows Templ, Go compiler and [golangci-lint](https://golangci-lint.run/)\n  errors, if any, and errors from [custom watchers](#custom-watchers) in the browser.\n  Templ's watcher just prints errors to the stdout and continues to display\n  the last valid state.\n- ⚙️ Templiér provides more configuration options (TLS, debounce, exclude globs, etc.).\n\n## Custom Watchers 👁️👁️\n\nCustom watchers let you change how Templiér behaves for files that match any of\nthe `include` globs, and they can be used for the use cases shown below.\n\nThe `requires` option lets you override the default behavior:\n\n- empty field/string: no extra action, just execute `cmd`.\n- `reload`: Only reload all open browser tabs.\n- `restart`: Restarts the server without rebuilding.\n- `rebuild`: Requires the server to be rebuilt and restarted (standard behavior).\n\nIf custom watcher `A` requires `reload` but custom watcher `B` requires `rebuild`,\n`rebuild` will be chosen once all custom watchers have finished executing.\n\n### Custom Watcher Example: JavaScript Bundler\n\nThe following custom watcher watches for `.js` file updates and automatically runs\nthe CLI command `npm run js:bundle`, after which all browser tabs will be reloaded\nusing `requires: reload`. `fail-on-error: true` means that if `eslint` or `esbuild`\nfails, their error output will be shown directly in the browser.\n\n```yaml\ncustom-watchers:\n  - name: Bundle JS\n    cmd: npm run bundle:js\n    include: [\"*.js\"]\n    exclude: [\"path/to/your/dist.js\"]\n    fail-on-error: true\n    debounce:\n    # reload browser after successful bundling\n    requires: reload\n```\n\nThe `cmd` above refers to a script defined in `package.json` scripts:\n\n```json\n\"scripts\": {\n  \"bundle:js\": \"eslint . \u0026\u0026 esbuild --bundle --minify --outfile=./dist.js server/js/bundle.js\",\n  \"lint:js\": \"eslint .\"\n},\n```\n\n### Custom Watcher Example: TailwindCSS and PostCSS\n\n[TailwindCSS](https://tailwindcss.com/) and [PostCSS](https://postcss.org/) are often\nused to simplify CSS styling, and a custom watcher enables Templiér to hot-reload the\nstyles on changes:\n\nFirst, configure `postcss.config.js`:\n\n```js\nmodule.exports = {\n  content: [\n    \"./server/**/*.templ\", // Include any .templ files\n  ],\n  plugins: [require(\"tailwindcss\"), require(\"autoprefixer\")],\n};\n```\n\nand `tailwind.config.js`:\n\n```js\n/** @type {import('tailwindcss').Config} */\nmodule.exports = {\n  content: [\"./**/*.{html,js,templ}\"],\n  theme: {\n    extend: {},\n  },\n  plugins: [require(\"tailwindcss\"), require(\"autoprefixer\")],\n};\n```\n\nCreate a `package.json` file and install all necessary dev dependencies:\n\n```sh\nnpm install tailwindcss postcss postcss-cli autoprefixer --save-dev\n```\n\nAdd the scripts to `package.json` (where `input.css` is your main CSS\nfile containing your global custom styles and `public/dist.css` is the built CSS\noutput file that's linked to in your HTML):\n\n```json\n\"scripts\": {\n  \"build:css\": \"postcss ./input.css -o ./public/dist.css\",\n  \"watch:css\": \"tailwindcss -i ./input.css -o ./public/dist.css --watch\"\n},\n```\n\nFinally, define a Templiér custom watcher to watch all Templ and CSS files and reload the browser:\n\n```yaml\n- name: Build CSS\n  cmd: npm run build:css\n  include: [\"*.templ\", \"input.css\"]\n  exclude: [\"path/to/your/dist.css\"]\n  fail-on-error: true\n  debounce:\n  requires: reload\n```\n\nNOTE: if your `dist.css` is embedded, you may need to use `requires: rebuild`.\n\n### Custom Watcher Example: Reload on config change\n\nNormally, Templiér rebuilds and restarts the server when any file changes except\nfor `.templ` files. However, when a config file changes, you usually don't need\nto rebuild the server. Restarting it may be sufficient:\n\n```yaml\n- name: Restart server on config change\n  cmd: # No command, just restart\n  include: [\"*.toml\"] # Any TOML file\n  exclude:\n  fail-on-error:\n  debounce:\n  requires: restart\n```\n\n## How Templiér works\n\nTempliér acts as a file watcher, proxy server and process manager.\nOnce Templiér is started, it runs `templ generate --watch` in the background and begins\nwatching files in the `app.dir-src-root` directory.\nOn start and on file change, it automatically builds your application server executable\nand saves it in the OS temp directory (cleaned up on exit at the latest), assuming that\nthe main package is specified by the `app.dir-cmd` directory.\nCustom Go compiler arguments can be specified with `compiler`. Once built, the application server\nexecutable is launched with `app.flags` CLI parameters and the working directory\nset to `app.dir-work`. When necessary, the application server process is shut down\ngracefully, rebuilt, linted and restarted.\nOn `.templ` file changes Templiér only tries to compile and lint the server code\nwithout refreshing the page.\n\nTempliér hosts your application under the URL specified by `templier-host` and proxies\nall requests to the application server process it launches, injecting Templiér\nJavaScript that opens a websocket connection back to Templiér from the browser tab\nto listen for events and reload or display status information when needed.\nIn the CLI console logs, all Templiér logs are prefixed with 🤖,\nwhile application server logs are displayed without the prefix.\n\n## Development\n\nRun the tests using `go test -race ./...` and use the latest version of\n[golangci-lint](https://golangci-lint.run/) to ensure code integrity.\n\n### Building\n\nInstall Templiér using the following command in the repository root directory:\n\n```sh\ngo install .\n```\n\nThis installs the `templier` binary into your Go bin directory.\nIf `templier` isn't found afterwards, make sure your Go bin directory is on\nyour `PATH`: https://go.dev/wiki/GOPATH\n\n### Important Considerations\n\n- Templiér currently doesn't support Windows.\n- When measuring performance, make sure you're not running against the Templiér proxy\n  that injects the JavaScript for auto-reloading because it will be slower and should\n  only be used for development. Instead, use the direct host address of your application\n  server specified by `app.host` in your `templier.yml` configuration.\n- Templiér's JavaScript injection uses the `GET /__templier/events` HTTP endpoint for\n  its websocket connection. Make sure it doesn't collide with your application's paths.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fromshark%2Ftemplier","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fromshark%2Ftemplier","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fromshark%2Ftemplier/lists"}