{"id":50937377,"url":"https://github.com/rockofox/servant-miso-starter","last_synced_at":"2026-06-17T10:32:29.115Z","repository":{"id":361409122,"uuid":"1247595041","full_name":"rockofox/servant-miso-starter","owner":"rockofox","description":"A minimal Nix-first template for a full-stack Haskell app","archived":false,"fork":false,"pushed_at":"2026-05-30T13:23:05.000Z","size":665,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-30T15:11:23.161Z","etag":null,"topics":["functional-programming","haskell","miso","servant","starter","template"],"latest_commit_sha":null,"homepage":"","language":"Nix","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/rockofox.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":"2026-05-23T14:24:01.000Z","updated_at":"2026-05-30T13:23:09.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/rockofox/servant-miso-starter","commit_stats":null,"previous_names":["rockofox/servant-miso-starter"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/rockofox/servant-miso-starter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rockofox%2Fservant-miso-starter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rockofox%2Fservant-miso-starter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rockofox%2Fservant-miso-starter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rockofox%2Fservant-miso-starter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rockofox","download_url":"https://codeload.github.com/rockofox/servant-miso-starter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rockofox%2Fservant-miso-starter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34445180,"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-17T02:00:05.408Z","response_time":127,"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":["functional-programming","haskell","miso","servant","starter","template"],"created_at":"2026-06-17T10:32:25.314Z","updated_at":"2026-06-17T10:32:29.093Z","avatar_url":"https://github.com/rockofox.png","language":"Nix","funding_links":[],"categories":[],"sub_categories":[],"readme":"# servant-miso-starter\n\nA minimal Nix-first template for a full-stack Haskell app:\n\n- **Backend**: [Servant](https://docs.servant.dev/) on Warp\n- **Frontend**: [Miso](https://haskell-miso.org/) compiled to WebAssembly via GHC's WASM backend\n- **Shared types**: a tiny `myapp-api` package that both sides import. Change a type once, fail to compile on both sides\n\n## Prerequisites\n\nNixOS / Nix with flakes enabled. That's it. GHC, the WASM toolchain, cabal,\n`ghciwatch`, everything else comes from the flake.\n\n## Quick start\n\n```sh\ndirenv allow   # or: nix develop\ndev            # watches backend + frontend, serves on :8080\n```\n\nThen open \u003chttp://localhost:8080\u003e.\n\n`dev` runs both watchers via [hivemind](https://github.com/DarthSim/hivemind).\nCtrl+C kills everything cleanly.\n\n## Dev workflow\n\n### All-in-one\n\n```sh\ndev\n```\n\n### Separately (two terminals)\n\n**Terminal 1 (backend):**\n```sh\nnix develop\nghcid --command='cabal repl lib:myapp-server' \\\n      --reload=myapp-api/src --reload=myapp-server/src \\\n      --warnings --run=MyApp.Server.main\n```\n\n**Terminal 2 (WASM UI):**\n```sh\nnix develop .#wasm\nghciwatch \\\n  --command='wasm32-wasi-cabal repl --project-file=cabal.project.ui myapp-ui' \\\n  --watch myapp-api/src --watch myapp-ui/app \\\n  --after-startup-shell ./scripts/build-ui.sh \\\n  --after-reload-shell ./scripts/build-ui.sh\n```\n\n### One-off builds\n\n```sh\n# Native packages (api + server)\nnix build\n\n# WASM UI. Must be run inside the WASM shell.\nnix develop .#wasm\n./scripts/build-ui.sh\n```\n\n## Environment\n\n| Var                | Default           | Purpose                   |\n|--------------------|-------------------|---------------------------|\n| `MYAPP_PORT`       | `8080`            | Server bind port          |\n| `MYAPP_STATIC_DIR` | `myapp-ui/static` | Directory served on `Raw` |\n\n## Renaming the project\n\nPick a name (e.g. `widget`), then from the repo root:\n\n```sh\n# rename module references and project name\nfind . -type f \\\n  \\( -name '*.hs' -o -name '*.cabal' -o -name 'cabal.project*' \\\n  -o -name 'flake.nix' -o -name '*.md' -o -name '*.html' -o -name '*.js' \\) \\\n  -not -path './.git/*' -not -path './dist-newstyle/*' \\\n  -exec sed -i 's/MyApp/Widget/g; s/myapp/widget/g; s/MYAPP/WIDGET/g' {} +\n\n# rename package directories\ngit mv myapp-api    widget-api\ngit mv myapp-server widget-server\ngit mv myapp-ui     widget-ui\n\n# rename module directories\nmv widget-api/src/MyApp    widget-api/src/Widget    2\u003e/dev/null || true\nmv widget-server/src/MyApp widget-server/src/Widget 2\u003e/dev/null || true\nmv widget-ui/app/MyApp     widget-ui/app/Widget     2\u003e/dev/null || true\n```\n\nThen rename the `.cabal` files to match (`myapp-api.cabal` → `widget-api.cabal`, etc.).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frockofox%2Fservant-miso-starter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frockofox%2Fservant-miso-starter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frockofox%2Fservant-miso-starter/lists"}