{"id":22972155,"url":"https://github.com/niclas-ahden/joy","last_synced_at":"2026-01-16T03:16:22.216Z","repository":{"id":267487785,"uuid":"901401363","full_name":"niclas-ahden/joy","owner":"niclas-ahden","description":"Roc framework for full-stack web apps","archived":false,"fork":false,"pushed_at":"2026-01-12T12:46:25.000Z","size":2663,"stargazers_count":28,"open_issues_count":0,"forks_count":3,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-01-12T19:47:38.050Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/niclas-ahden.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-12-10T15:36:03.000Z","updated_at":"2026-01-12T12:46:30.000Z","dependencies_parsed_at":"2025-03-06T23:19:23.324Z","dependency_job_id":"a87287ee-a5d9-4d1b-a33a-78940f574214","html_url":"https://github.com/niclas-ahden/joy","commit_stats":null,"previous_names":["niclas-ahden/joy"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/niclas-ahden/joy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/niclas-ahden%2Fjoy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/niclas-ahden%2Fjoy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/niclas-ahden%2Fjoy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/niclas-ahden%2Fjoy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/niclas-ahden","download_url":"https://codeload.github.com/niclas-ahden/joy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/niclas-ahden%2Fjoy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28477076,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T03:13:13.607Z","status":"ssl_error","status_checked_at":"2026-01-16T03:11:47.863Z","response_time":107,"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":[],"created_at":"2024-12-14T23:00:34.637Z","updated_at":"2026-01-16T03:16:22.202Z","avatar_url":"https://github.com/niclas-ahden.png","language":"Rust","funding_links":[],"categories":["Projects","Roc Platforms 🏢"],"sub_categories":[],"readme":"# Joy\n\nA framework for building full-stack web apps in Roc!\n\nJoy is a jolt of happiness for those who want a fast, productive, fun, and statically-typed environment for full-stack development.\n\nIt's a fork of Luke Boswell's awesome [Roc Experiment JS DOM](https://github.com/lukewilliamboswell/roc-experiment-js-dom) which opened up the avenue for me to use Roc on the front-end. Thank you Luke!\n\n## Goals\n\nJoy should provide:\n* A convenient way of writing apps that run on the server and client (sometimes called \"isomorphic\" apps)\n* A convenient way of communicating between the front- and back-end (perhaps [Server Functions](https://book.leptos.dev/server/25_server_functions.html), or message-passing over websockets, or ...)\n* Geat developer experience (feedback, iteration time, tooling, etc.)\n* Great performance for the vast majority of apps, but not at any cost (in line with Roc's philosophy of aiming for Go's performance rather than Rust's)\n\n## Status\n\nJoy is fun to play with, but it's in early development, not production-ready, is missing most of its intended features, and will change a lot. Even the underpinning technologies are not production-ready ([Roc](https://www.roc-lang.org), [`percy-dom`](https://github.com/chinedufn/percy)). Here be dragons!\n\nYou can already build full-stack or single-page applications in it but the functionality is severely limited. Have a look at the [examples](https://github.com/niclas-ahden/joy/tree/main/examples) to get a grasp on what's currently supported.\n\nHave fun and expect breaking changes!\n\n## Example\n\nA client-side counter:\n\n```roc\napp [Model, init!, update!, render] {\n    pf: platform \"../platform/main.roc\",\n    html: \"https://github.com/niclas-ahden/joy-html/releases/download/v0.10.0/VM_GLBCvmmdZAxFHzkRqOX2YHYxt4qPVrs5Omm2L374.tar.br\",\n}\n\nimport html.Html exposing [Html, div, button, text]\nimport html.Event\nimport pf.Action exposing [Action]\n\nModel : I64\n\ninit! : Str =\u003e Model\ninit! = |_flags| 0\n\nEvent : [\n    UserClickedDecrement,\n    UserClickedIncrement,\n]\n\nupdate! : Model, Str, List U8 =\u003e Action Model\nupdate! = |model, raw, _payload|\n    when decode_event(raw) is\n        UserClickedDecrement -\u003e Num.sub_wrap(model, 1) |\u003e Action.update\n        UserClickedIncrement -\u003e Num.add_wrap(model, 1) |\u003e Action.update\n\nrender : Model -\u003e Html Model\nrender = |model|\n    div(\n        [],\n        [\n            button([Event.on_click(encode_event(UserClickedIncrement))], [text(\"+\")]),\n            text(Inspect.to_str(model)),\n            button([Event.on_click(encode_event(UserClickedDecrement))], [text(\"-\")]),\n        ],\n    )\n\nencode_event : Event -\u003e Str\nencode_event = |event| Inspect.to_str(event)\n\ndecode_event : Str -\u003e Event\ndecode_event = |raw|\n    when raw is\n        \"UserClickedIncrement\" -\u003e UserClickedIncrement\n        \"UserClickedDecrement\" -\u003e UserClickedDecrement\n        _ -\u003e crash(\"Unsupported event type \\\"${raw}\\\"\")\n```\n\n[See more examples](https://github.com/niclas-ahden/joy/tree/main/examples)\n\n## Try it out\n\nClone the repo and use the included Nix flake to set up your development environment:\n\n```sh\n$ nix develop # Oh, lord, have mercy! This is great!\n```\n\nIf you don't want to use Nix then please install:\n\n* [`roc`](https://www.roc-lang.org/install) (see [Roc compiler and roc_std versions](#roc-compiler-and-roc_std-versions) below)\n* `zig 13`\n* `rustc`\n* `cargo`\n* `lld`\n* [`wasm-pack`](https://rustwasm.github.io/wasm-pack/installer/)\n* `simple-http-server`\n* `inotify-tools` (on Linux)\n* `watchexec`\n\n### Run an example\n\nPick an [example](https://github.com/niclas-ahden/joy/tree/main/examples) and run it like so:\n\n```sh\n$ ./watch.sh examples/hello.roc\n```\n\nThe application should now be available at: [`http://localhost:3000`](http://localhost:3000)\n\nStart modifying the example to get a feel for it. Refresh the browser to see your changes (the app is recompiled on change but there's no browser hot-reloading yet).\n\n### Deploying an app\n\n#### Full-stack apps\n\nTBD\n\n#### SPA / Client-side apps\n\nDelete existing assets then build for release:\n\n```sh\n$ rm -rf ./www/pkg\n$ ./build.sh --release examples/hello.roc\n```\n\nYou'll end up with a complete front-end app in the `www` directory. You can deploy that anywhere as you see fit.\n\n## Contributing\n\nContributions are very welcome, including feature requests, design discussion, etc.\n\n## Development setup\n\nDo everything under \"Try it out\" and you're golden.\n\nThe `./watch.sh` script will recompile your Roc application and the client-side platform on change.\n\n### CLI\n\nUsing WASI to debug the Roc FFI without the complications of `wasm-pack` and the browser.\n\nInstall [`bytecodealliance/cargo-wasi`](https://github.com/bytecodealliance/cargo-wasi), then:\n\n```sh\n$ ./run-cli.sh examples/hello.roc\n```\n\n### Roc compiler and `roc_std` versions\n\nThe Joy client-side platform is written in Rust and depends on the crate `roc_std` from the Roc project. You must ensure that your Roc compiler version is the same as the `roc_std` version that Joy uses.\n\n#### Using Nix flake (recommended)\n\nThis is taken care of for you if you use the Nix flake. We ensure that the Roc compiler version in `flake.lock` and the `roc_std` version in `Cargo.lock` are the same.\n\nIf you want to change which versions are used you can specify the version or commit in `flake.nix` and `Cargo.toml`.\n\nYou can also just update to the latest commit of both like so:\n\n```sh\n$ nix flake update roc\n$ cargo update roc_std\n```\n\n#### Not using Nix flake\n\nIf you're not using the Nix flake you'll need to ensure that the versions line up yourself. It's probably easiest to install the version of Roc that you'd like and then specify that version of `roc_std` in `Cargo.toml`.\n\n## Sponsors\n\nJoy is sponsored by the real estate agency [BOSTHLM Fastighetsmäklare](https://www.bosthlm.se) which thrives by using technology to bolster its agents and business. Thank you!\n\nHave a look at their search feature on [www.bosthlm.se/till-salu](https://www.bosthlm.se/till-salu) which is a front-end application written in Roc.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fniclas-ahden%2Fjoy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fniclas-ahden%2Fjoy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fniclas-ahden%2Fjoy/lists"}