{"id":32167669,"url":"https://github.com/scorsi/umbra","last_synced_at":"2026-02-19T08:02:45.777Z","repository":{"id":62430631,"uuid":"268353152","full_name":"scorsi/umbra","owner":"scorsi","description":"umbra helps you make your GenServer rocks in lesser code","archived":false,"fork":false,"pushed_at":"2020-06-05T10:33:33.000Z","size":101,"stargazers_count":0,"open_issues_count":7,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-02-18T05:32:12.129Z","etag":null,"topics":["elixir","elixir-library"],"latest_commit_sha":null,"homepage":"","language":"Elixir","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/scorsi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-05-31T19:53:13.000Z","updated_at":"2026-02-10T07:52:49.000Z","dependencies_parsed_at":"2022-11-01T20:18:42.977Z","dependency_job_id":null,"html_url":"https://github.com/scorsi/umbra","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/scorsi/umbra","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scorsi%2Fumbra","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scorsi%2Fumbra/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scorsi%2Fumbra/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scorsi%2Fumbra/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scorsi","download_url":"https://codeload.github.com/scorsi/umbra/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scorsi%2Fumbra/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29608152,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-19T06:47:36.664Z","status":"ssl_error","status_checked_at":"2026-02-19T06:45:47.551Z","response_time":117,"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":["elixir","elixir-library"],"created_at":"2025-10-21T15:34:53.706Z","updated_at":"2026-02-19T08:02:45.772Z","avatar_url":"https://github.com/scorsi.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Umbra [![Build Status](https://travis-ci.com/scorsi/umbra.svg?branch=master)](https://travis-ci.com/scorsi/umbra) [![Coverage Status](https://coveralls.io/repos/github/scorsi/umbra/badge.svg?branch=master)](https://coveralls.io/github/scorsi/umbra?branch=master) [![Hex.pm](https://img.shields.io/hexpm/v/umbra.svg)](https://hex.pm/packages/umbra) [![Hex.pm](https://img.shields.io/hexpm/dt/umbra.svg)](https://hex.pm/packages/umbra)\n\n\nUmbra helps you make your GenServer rocks in lesser code, inspired by ExActor.\n\nWe all know [ExActor](https://github.com/sasa1977/exactor) which is a good project... which was... here the issues of ExActor:\n- is not maintained since 2017,\n- didn't support last GenServer functionalities like `continue`,\n- did generate a lot of warnings in the user codebase like unused variables,\n- isn't extensible.\n\nUmbra has been inspired by ExActor, but nothing more, it is a totally re-write.\n Umbra has a lightweight, well tested, highly documented and very comprehensive codebase.\n\nThe main differences with ExActor are :\n- you have to declare function like you would normally do in the `handle_*` functions or `GenServer.*` call.\n For example: `{:set_state, new_state}` and not like `set_state(new_state)`.\n\nUmbra understands what you write :\n - in the function definition,\n - in the when guard,\n - or in the state alias.\n\nIt will automatically :\n - shadow unused variables,\n - un-shadow necessary variables,\n - create variables to optimize code,\n - reduce code complexity when needed \n - and all of this without your attention.\n\nActually Umbra lacks some features like `multicall` and `abcast` in addition to the `defstart`\n which is internally done and not configurable to the user.\n\nIf you feel that Umbra lacks something or if you dive into a bug,\n don't hesitate to create an issue or create a PR.\n\n## Installation\n\nAdd umbra for Elixir as a dependency in your mix.exs file.\n\n```elixir\ndef deps do\n  [\n    {:umbra, \"~\u003e 0.1.0\"},\n  ]\nend\n```\n\nAfter you are done, fetch the new dependency:\n\n```bash\n$ mix deps.get\n```\n\n## Getting started\n\nTo get started, after adding the dependency to your mix project, you only have\n to use the [`Umbra.GenServer`](https://hexdocs.pm/umbra/Umbra.GenServer.html) \n and your GenServer already did start to being generated.\n\nHere is a really simple exemple:\n\n```elixir\ndefmodule BasicGenServer do\n  use Umbra.GenServer\n\n  definit state: state, do: {:ok, state}\n\n  defcall {:get_state}, state: state, do: {:reply, state, state}\n\n  defcast {:set_state, new_state}, do: {:noreply, new_state}\n\n  defcast {:increment}, state: state, do: {:noreply, state + 1}\n\n  defcast {:decrement}, state: state, do: {:noreply, state - 1}\nend\n\n{:ok, pid} = BasicGenServer.start_link(0) # state = 0\n:ok = BasicGenServer.increment(pid) # state = 1\n:ok = BasicGenServer.increment(pid) # state = 2\n:ok = BasicGenServer.decrement(pid) # state = 1\n:ok = BasicGenServer.set_state(pid, 42) # state = 42\n{:ok, 42} = BasicGenServer.get_state(pid)\n```\n\nTo deep further, please take a look at [HexDocs](https://hexdocs.pm/umbra).\n\n## What do Umbra under the hood\n\nHere is a notable example:\n```elixir\ndefcall {:do_computation, {a, b}, _c}, when: is_number(a), state: state do\n  {:reply, a + b, state}\nend\n\n# The generated code\ndef do_computation(pid, {a, _b} = umbra_arg_1, c) when is_number(a) do\n  GenServer.call(pid, {:do_computation, umbra_arg_1, c})\nend\ndef handle_call({:do_computation, {a, b}, _c}, _from, state) when is_number(a) do\n  {:reply, a + b, state}\nend\n```\nHere what you can notice in this example:\n- Umbra add a new variable `umbra_arg_1` to optimize the code. Passing `{a, b}` to the GenServer call\n could be simpler but not optimized.\n- Umbra automatically shadow the `b` variable to avoid warning for unused variable.\n But it didn't do the same for the `a` variable since it is used in the when clause.\n- Umbra did automatically un-shadow the `c` variable in the client-side function to avoid warning because\n it is used in the GenServer call. \n\n_Note: actually un-shadow and variable optimizations are not yet implemented but will come in the next updates._\n\n## Tests\n\nThe project is tested for:\n\n| Elixir version | OTP version |\n| --- | --- |\n| 1.7.4 | 21.3 |\n| 1.7.4 | 22.3 |\n| 1.8.2 | 21.3 |\n| 1.8.2 | 22.3 |\n| 1.9.4 | 21.3 |\n| 1.9.4 | 22.3 |\n| 1.10.3 | 21.3 |\n| 1.10.3 | 22.3 |\n| 1.10.3 | 23.0 |\n\nCompatibility-issues only in tests for `otp \u003c 21` caused primarily by the missing GenServer `continue` feature.\n\n## Contributing\n\nContributions are welcome!\n\n- [Fork it](https://github.com/scorsi/umbra/fork)!\n- Create your feature branch (`git checkout -b your-new-feature`).\n- Commit your change in only one commit (`git commit -am \"Add my new feature\"`).\n- Push your change on your fork (`git push origin your-new-feature`).\n- Create a new [Pull Request](https://github.com/scorsi/umbra/compare).\n\n## Author\n\nSylvain Corsini ([@scorsi](https://github.com/scorsi))\n\n## Credits\n\nThis project took inspiration from the well-known [ExActor](https://github.com/sasa1977/exactor).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscorsi%2Fumbra","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscorsi%2Fumbra","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscorsi%2Fumbra/lists"}