{"id":13809248,"url":"https://github.com/jsonmaur/namor","last_synced_at":"2025-03-26T20:31:37.874Z","repository":{"id":65588340,"uuid":"589137275","full_name":"jsonmaur/namor","owner":"jsonmaur","description":"A subdomain-safe name generator","archived":false,"fork":false,"pushed_at":"2023-05-11T02:57:27.000Z","size":112,"stargazers_count":13,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-10-30T07:08:34.281Z","etag":null,"topics":["dictionary","elixir","hosting","name-generator","subdomain"],"latest_commit_sha":null,"homepage":"https://hexdocs.pm/namor","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/jsonmaur.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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}},"created_at":"2023-01-15T07:15:49.000Z","updated_at":"2024-07-12T01:22:47.000Z","dependencies_parsed_at":"2023-02-16T12:51:11.016Z","dependency_job_id":"2a1fa583-e91b-4985-a926-1d6ef5a1d3b2","html_url":"https://github.com/jsonmaur/namor","commit_stats":null,"previous_names":["jsonmaur/namor.ex"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsonmaur%2Fnamor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsonmaur%2Fnamor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsonmaur%2Fnamor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsonmaur%2Fnamor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jsonmaur","download_url":"https://codeload.github.com/jsonmaur/namor/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245731505,"owners_count":20663200,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["dictionary","elixir","hosting","name-generator","subdomain"],"created_at":"2024-08-04T01:02:12.850Z","updated_at":"2025-03-26T20:31:35.017Z","avatar_url":"https://github.com/jsonmaur.png","language":"Elixir","funding_links":[],"categories":["Text and Numbers"],"sub_categories":[],"readme":"# Namor\n\nNamor is a name generator for Elixir that creates random, url-friendly names. This comes in handy if you need to generate unique subdomains like many PaaS/SaaS providers do, or unique names for anything else. Supports compile-time dictionary loading, subdomain validation with reserved names, custom dictionaries and reserved word lists, alternate dictionaries, and more.\n\n[See a demo here.](https://namor.jsonmaur.com) Also available for [Javascript](https://github.com/jsonmaur/namor.js).\n\n\u003e _Please Note: Generated names are not always guaranteed to be unique. To reduce the chances of collision, you can increase the length of the trailing number ([see here for collision stats](#collision-stats)). Always be sure to check your database before assuming a generated value is unique._\n\n- [Installation](#installation)\n- [Getting Started](#getting-started)\n- [Collision Stats](#collision-stats)\n- [Custom Dictionaries](#custom-dictionaries)\n\n## Installation\n\n```elixir\ndef deps do\n  [\n    {:namor, \"~\u003e 1.0\"}\n  ]\nend\n```\n\n## Getting Started\n\n```elixir\niex\u003e require Namor\n\niex\u003e Namor.generate()\n{:ok, \"sandwich-invent\"}\n\niex\u003e Namor.generate(salt: 5)\n{:ok, \"sandwich-invent-s86uo\"}\n\niex\u003e Namor.generate(words: 3, dictionary: :rugged)\n{:ok, \"savage-whiskey-stain\"}\n```\n\nAn example module that generates subdomains for users (does not check for database uniqueness):\n\n```elixir\ndefmodule MyApp.Subdomains do\n  use Namor\n\n  @salt_length 5\n\n  def get_new_subdomain(nil), do: Namor.generate(salt: @salt_length)\n\n  def get_new_subdomain(name) do\n    with false \u003c- Namor.reserved?(name),\n         subdomain \u003c- Namor.with_salt(name, @salt_length),\n         true \u003c- Namor.subdomain?(subdomain) do\n      {:ok, subdomain}\n    else\n      _ -\u003e {:error, :invalid_subdomain}\n    end\n  end\nend\n```\n\n## Collision Stats\n\nThe following stats give you the total number of permutations based on the word count (without a salt), and can help you make a decision on how long to make your salt. This data is based on the number of words we currently have in our [dictionary files](https://github.com/jsonmaur/namor/tree/master/dict).\n\n##### `:default` dictionary\n\n- 1-word combinations: 7,948\n- 2-word combinations: 11,386,875\n- 3-word combinations: 12,382,548,750\n- 4-word combinations: 23,217,278,906,250\n\n##### `:rugged` dictionary\n\n- 1-word combinations: 735\n- 2-word combinations: 127,400\n- 3-word combinations: 14,138,880\n- 4-word combinations: 3,958,886,400\n\n## Custom Dictionaries\n\nIn order for our dictionary files to be loaded into your application during compilation, [`generate/1`](https://hexdocs.pm/namor/Namor.html#generate/1) and [`reserved?/1`](https://hexdocs.pm/namor/Namor.html#reserved?/1) are defined as a macros. This means they can only be used after calling `use Namor` or `require Namor`, which should be done during compilation (and not inside a function). If you want to use your own dictionary, consider calling [`Namor.Helpers.get_dict!/2`](https://hexdocs.pm/namor/Namor.Helpers.html#get_dict!/2) in a place that executes during compilation and **not** runtime. For example:\n\n```\n┌── dictionaries/\n│  ┌── foobar/\n│  │  ┌── adjectives.txt\n│  │  ├── nouns.txt\n│  │  └── verbs.txt\n│  └── reserved.txt\n```\n\n```elixir\ndefmodule MyApp.Subdomains do\n  use Namor\n\n  @salt_length 5\n  @base_path Path.expand(\"./dictionaries\", __DIR__)\n\n  @reserved Namor.Helpers.get_dict!(\"reserved.txt\", @base_path)\n  @dictionary Namor.Helpers.get_dict!(:foobar, @base_path)\n\n  defp reserved, do: @reserved\n  defp dictionary, do: @dictionary\n\n  def get_new_subdomain(nil), do: Namor.generate([salt: @salt_length], dictionary())\n\n  def get_new_subdomain(name) do\n    with false \u003c- Namor.reserved?(name, reserved()),\n         subdomain \u003c- Namor.with_salt(name, @salt_length),\n         true \u003c- Namor.subdomain?(subdomain) do\n      {:ok, subdomain}\n    else\n      _ -\u003e {:error, :invalid_subdomain}\n    end\n  end\nend\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjsonmaur%2Fnamor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjsonmaur%2Fnamor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjsonmaur%2Fnamor/lists"}