@lanlinling/env-config
v0.0.1
Published
Personal convenience layer: maps provider IDs to this machine's existing shell env var names (from ~/.zshrc), so consuming projects don't need to re-declare API keys. Not a general-purpose library — the naming convention is specific to one person's setup.
Readme
@lanlinling/env-config
Personal convenience layer for @lanlinling/llm-providers /
@lanlinling/audio-providers / @lanlinling/media-providers.
The other three packages are deliberately "pure" — every function takes
apiKey/baseUrl explicitly, nothing reads process.env for credentials.
That's the right default for a shared library, but it means every
consuming project has to know which env var name each provider's key
lives in. This package is that mapping, encoded once, for one machine's
~/.zshrc conventions — so you maintain the actual secrets in exactly one
place and every project just asks "give me anthropic's config."
This is not a general-purpose package. The env var names below are
specific to how one person's shell is set up. If you fork this repo for
your own use, rewrite the override tables in src/index.ts to match your
own env var names.
Install
{
"dependencies": {
"@lanlinling/env-config": "github:bluemomo112/ai-providers#path:packages/env-config"
}
}# pnpm-workspace.yaml
onlyBuiltDependencies:
- "@lanlinling/env-config"Usage
import { resolveLLMEnv, resolveTTSEnv, resolveASREnv, resolveImageEnv, resolveVideoEnv } from '@lanlinling/env-config';
import { getModel } from '@lanlinling/llm-providers';
import { generateTTS } from '@lanlinling/audio-providers';
import { generateImage } from '@lanlinling/media-providers';
const { model } = getModel({
providerId: 'anthropic',
modelId: 'claude-sonnet-4-6',
...resolveLLMEnv('anthropic'), // { apiKey, baseUrl } read from process.env
});
const tts = await generateTTS(
{ providerId: 'qwen-tts', modelId: 'qwen3-tts-flash', voice: 'Cherry', ...resolveTTSEnv('qwen-tts') },
'text to speak',
);
const image = await generateImage(
{ providerId: 'seedream', ...resolveImageEnv('seedream') },
{ prompt: 'a small robot watering a plant' },
);Each resolver reads process.env fresh on every call — nothing is cached
or copied into a file, so updating a key in ~/.zshrc (and opening a new
shell) is all you need; no project needs to be reconfigured.
Current mapping
| Category | Provider | Env var |
| --- | --- | --- |
| LLM | qwen | DASHSCOPE_API_KEY |
| LLM | doubao | ARK_API_KEY |
| LLM | onehub | COCO_API_KEY |
| LLM | everything else | {PROVIDER_ID}_API_KEY / {PROVIDER_ID}_BASE_URL |
| TTS | qwen-tts | DASHSCOPE_API_KEY |
| TTS | minimax-tts | MINIMAX_API_KEY |
| TTS | doubao-tts | DOUBAO_TTS_API_KEY — not ARK_API_KEY, see audio-providers/TROUBLESHOOTING.md |
| ASR | qwen-asr | DASHSCOPE_API_KEY |
| Image | seedream | ARK_API_KEY |
| Image | qwen-image | DASHSCOPE_API_KEY |
| Image | minimax-image | MINIMAX_API_KEY |
| Image | aihubmix | AIHUBMIX_API_KEY (already matches the generic convention) |
| Video | seedance | ARK_API_KEY |
| Video | minimax-video | MINIMAX_API_KEY |
Anything not listed falls back to the generic
{PROVIDER_ID_UPPERCASE_WITH_UNDERSCORES}_API_KEY convention.
Known gap: ANTHROPIC_API_KEY (and ANTHROPIC_BASE_URL) are not
currently in ~/.zshrc — they only exist inside one project's
.env.local, so resolveLLMEnv('anthropic') will return an empty
apiKey on any other project until that's moved to the shell profile.
