Vault
Vault is a lightweight Elixir library for process-scoped global data storage that propagates to linked process children.
Due to Elixir's actor model nature, it's common for a process to have global context that is valid for every function call inside this process (and its children).
For example, this context can include:
- A user when processing a user's request
- A tenant in a multi-tenant application
- Rate limiting buckets/quotas
- Cache namespaces
- API or client versions
- And many more, depending on your application domain
Vault provides you a guarantee that the context is only defined once when calling Vault.init/1, so you won't override it by accident. However, if you need to split initializations, you can always use Vault.unsafe_merge/1, but the responsibility will fall on you.
Usage
# Initialize vault in parent process
Vault.init(current_user: %{id: 1, first_name: "Alice", role: "admin"})
# Access data from any linked child process
Task.async(fn ->
user = Vault.get(:current_user)
user.first_name # => "Alice"
end)
# Access data from the parent process itself
Vault.get(:current_user) # => %{id: 1, first_name: "Alice", role: "admin"}
Why Vault?
Instead of property-drilling context data through every function call, Vault provides access to shared data across your process tree. When used for immutable data - this is a cleaner and more maintainable approach, simplifying cognitive load when reasoning about your code.
The data is initialized only once and is immutable (unless you explicitly call unsafe_* functions).
The API mirrors Elixir's Map module for familiar data access.
Limitations
- Vault only propagates to linked processes. If you start a process without linking (e.g.,
Task.start/1), it won't have access to the vault.
Installation
def deps do
[
{:vault, "~> 0.2.0"}
]
end