Install
$ agentstack add skill-vinnie357-claude-skills-config ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README — it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming — see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps — measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Elixir Configuration
Guide for proper application configuration in Elixir, with emphasis on understanding and correctly using runtime vs compile-time configuration.
When to Activate
Use this skill when:
- Setting up or modifying application configuration
- Choosing between
config.exsandruntime.exs - Deciding between
Application.compile_envandApplication.get_env - Debugging configuration-related issues
- Working with releases or deployment configuration
- Migrating from
use Mix.Configtoimport Config - Writing libraries that need configuration
Critical Principle
> Runtime configuration is the preferred approach. Only use compile-time configuration when values must affect compilation itself.
Configuration Files
config/config.exs (Compile-Time)
Evaluated during project compilation, before your application starts.
import Config
# Basic configuration
config :my_app, MyApp.Repo,
database: "my_app_dev",
username: "postgres",
password: "postgres",
hostname: "localhost"
# Environment-specific config
config :my_app,
environment: config_env()
# Import environment-specific config files
import_config "#{config_env()}.exs"
Key characteristics:
- Runs at compile time
- Uses
import Config(notuse Mix.Config) - Can use
config_env()andconfig_target() - Can import other config files with
import_config/1 - Deep-merges keyword lists
- Library config.exs is NOT evaluated when used as a dependency
config/runtime.exs (Runtime)
Evaluated right before applications start in both Mix and releases.
import Config
# Read from environment variables
config :my_app, MyApp.Repo,
database: System.get_env("DATABASE_NAME") || "my_app_dev",
username: System.get_env("DATABASE_USER") || "postgres",
password: System.get_env("DATABASE_PASSWORD") || "postgres",
hostname: System.get_env("DATABASE_HOST") || "localhost",
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10")
# Conditional runtime configuration
if config_env() == :prod do
config :my_app, MyAppWeb.Endpoint,
secret_key_base: System.fetch_env!("SECRET_KEY_BASE"),
http: [port: String.to_integer(System.fetch_env!("PORT"))]
end
Key characteristics:
- Runs at application startup (both dev and prod)
- Executes in both Mix projects and releases
- Perfect for environment variables and runtime values
- Does NOT support
import_config/1 - Can use
System.get_envandSystem.fetch_env!
config/dev.exs, config/test.exs, config/prod.exs
Environment-specific compile-time configuration, typically imported from config.exs:
# config/config.exs
import_config "#{config_env()}.exs"
# config/dev.exs
import Config
config :my_app, MyApp.Repo,
show_sensitive_data_on_connection_error: true,
pool_size: 10
# config/test.exs
import Config
config :my_app, MyApp.Repo,
pool: Ecto.Adapters.SQL.Sandbox,
pool_size: 10
# config/prod.exs
import Config
# Production-specific compile-time config only
config :my_app, MyAppWeb.Endpoint,
cache_static_manifest: "priv/static/cache_manifest.json"
Accessing Configuration
Runtime Access (Preferred)
Use in function bodies to read configuration at runtime:
Application.get_env/3
defmodule MyApp.Service do
def start_link do
# Get with default value
timeout = Application.get_env(:my_app, :timeout, 5000)
GenServer.start_link(__MODULE__, timeout, name: __MODULE__)
end
end
When to use:
- Reading config in function bodies (most common)
- When a sensible default exists
- When config might change between environments
Application.fetch_env!/2
defmodule MyApp.Mailer do
def deliver(email) do
# Raise if not configured (for required config)
api_key = Application.fetch_env!(:my_app, :mailgun_api_key)
send_email(email, api_key)
end
end
When to use:
- Required configuration that must exist
- When you want explicit errors for missing config
- When no sensible default exists
Application.fetch_env/2
defmodule MyApp.Cache do
def get(key) do
case Application.fetch_env(:my_app, :cache_adapter) do
{:ok, adapter} -> adapter.get(key)
:error -> nil # No caching configured
end
end
end
When to use:
- Optional configuration
- When you need pattern matching on result
- When absence of config is a valid state
Compile-Time Access (Use Sparingly)
Use only when configuration must affect compilation:
Application.compile_env/3
defmodule MyApp.JSONEncoder do
# Only use compile_env when the value affects compilation
@json_library Application.compile_env(:my_app, :json_library, Jason)
def encode(data) do
# The specific library is compiled into the module
@json_library.encode(data)
end
end
When to use:
- Configuration affects which code gets compiled
- Performance-critical paths where indirection is costly
- Compile-time optimizations or code generation
Warning: Mix tracks compile-time config and raises errors if values diverge between compile and runtime.
Application.compile_env!/2
defmodule MyApp.Adapter do
# Raises at compile time if not configured
@adapter Application.compile_env!(:my_app, :storage_adapter)
def store(data) do
@adapter.put(data)
end
end
When to use:
- Required compile-time configuration
- Adapters or behaviors selected at compile time
Common Patterns
Five worked patterns — environment variables in runtime, dev/prod split, storing config_env() for runtime access, optional features, and child specs with runtime config: see references/patterns.md.
Anti-Patterns to Avoid
❌ Using compile_env for Runtime Values
# DON'T: Using compile_env for environment variables
defmodule MyApp.Service do
@api_key Application.compile_env(:my_app, :api_key)
def call do
# This won't work correctly in releases!
HTTPoison.get(url, [{"Authorization", @api_key}])
end
end
Why it's wrong: Environment variables aren't available at compile time in releases.
Correct approach:
defmodule MyApp.Service do
def call do
# Read at runtime
api_key = Application.fetch_env!(:my_app, :api_key)
HTTPoison.get(url, [{"Authorization", api_key}])
end
end
❌ Reading Other Application's Config
# DON'T: Directly access other app's configuration
defmodule MyApp do
def logger_level do
Application.get_env(:logger, :level) # Fragile coupling
end
end
Why it's wrong: Creates tight coupling and breaks encapsulation.
Correct approach:
# Configure it in your own app
# config/config.exs
config :my_app, :log_level, :info
# Then read your own config
defmodule MyApp do
def log_level do
Application.get_env(:my_app, :log_level, :info)
end
end
❌ Using Application Config in Libraries
# DON'T: In a library
defmodule MyLibrary do
def process(data) do
# Library reading its own application environment
timeout = Application.get_env(:my_library, :timeout, 5000)
do_work(data, timeout)
end
end
Why it's wrong: Library config.exs is not evaluated when used as a dependency.
Correct approach:
# DO: Accept options as arguments
defmodule MyLibrary do
def process(data, opts \\ []) do
timeout = Keyword.get(opts, :timeout, 5000)
do_work(data, timeout)
end
end
# Users configure in their application
defmodule MyApp.Worker do
def run do
opts = Application.get_env(:my_app, :my_library_opts, [])
MyLibrary.process(data, opts)
end
end
❌ Using Mix Module in Application Code
# DON'T: Use Mix.env() in application code
defmodule MyApp do
def environment do
Mix.env() # Won't work in releases!
end
end
Why it's wrong: Mix is not available in production releases.
Correct approach:
# Store it in config
# config/config.exs
config :my_app, :environment, config_env()
# Access from application environment
defmodule MyApp do
def environment do
Application.fetch_env!(:my_app, :environment)
end
end
Config Functions Reference
In Configuration Files
| Function | Description | Where to Use | |----------|-------------|--------------| | config/2 | Configure app with keyword list | All config files | | config/3 | Configure app key with value | All config files | | config_env/0 | Get current environment (:dev, :test, :prod) | All config files | | config_target/0 | Get build target | All config files | | import_config/1 | Import other config files | Not in runtime.exs |
In Application Code
| Function | Return Type | Use Case | |----------|-------------|----------| | Application.get_env/3 | value \| default | Runtime with default | | Application.fetch_env/2 | {:ok, value} \| :error | Runtime with pattern matching | | Application.fetch_env!/2 | value (raises if missing) | Required runtime config | | Application.compile_env/3 | value | Compile-time with default | | Application.compile_env!/2 | value (raises if missing) | Required compile-time config |
Migration Guide
Moving from use Mix.Config to import Config, and moving runtime values out of config.exs into runtime.exs: see references/migration.md.
Best Practices Summary
- Default to Runtime Configuration: Use
Application.get_env/3in function bodies - Use runtime.exs for Environment Variables: Never read env vars in
config.exs - Use compile_env Only When Necessary: Only when config affects compilation
- Libraries Should Not Use Application Config: Accept options as function arguments
- Never Use Mix in Application Code: Use
config_env()in config files, store result - Validate Required Config Early: Use
fetch_env!/2in application start for required values - Provide Sensible Defaults: Use
get_env/3with defaults for optional config - Document Configuration: Add comments explaining what each config key does
- Use runtime.exs for Releases: Essential for Elixir releases and deployments
- Store config_env() for Runtime Use: Can't call
config_env()outside config files
Debugging Configuration
Check Current Configuration
# In IEx
Application.get_all_env(:my_app)
# Check specific key
Application.fetch_env(:my_app, :some_key)
# See all applications
Application.loaded_applications()
Common Issues
Problem: Config not available in tests
# config/test.exs
import Config
config :my_app, :test_value, "configured"
Problem: Different values in dev vs release
Check that runtime.exs is being used and environment variables are set correctly.
Problem: Compile-time config not updating
# Clean and recompile
mix clean
mix compile
Resources
- Config Module Docs: https://hexdocs.pm/elixir/Config.html
- Application Module Docs: https://hexdocs.pm/elixir/Application.html
- Runtime Configuration Guide: https://hexdocs.pm/mix/Mix.Tasks.Release.html#module-runtime-configuration
Key Insights
> "Reading the application environment at runtime is the preferred approach."
> "If you are writing a library to be used by other developers, it is generally recommended to avoid the application environment, as the application environment is effectively a global storage."
> "config/config of a library is not evaluated when the library is used as a dependency, as configuration is always meant to configure the current project."
Configuration is a cross-cutting concern. Default to runtime configuration with Application.get_env/3, and only reach for compile-time configuration when you have a specific need for it that justifies the trade-offs.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: vinnie357
- Source: vinnie357/claude-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.