Lazy initialization for Cloudflare Workers.
npm install @rikkainc/lazyenv
pnpm install @rikkainc/lazyenv
bun add @rikkainc/lazyenv
Cloudflare Workers do not provide process.env
, so we cannot instantiate client libraries such as ai
, openai
, mysql
, or postgres
at the top level.
As a result, you might end up writing code like this:
app.post("/some-api-endpoint", async (c) => {
// You have to instantiate client libraries in the request handler context.
const openai = createOpenAI({
apiKey: c.env.OPENAI_API_KEY,
});
const model = openai("gpt-4o");
// ... use the model
})
In most Node.js projects, we simply instantiate client libraries at the top level:
const model = openai("gpt-4o");
app.post("/some-api-endpoint", async (c) => {
// ... use the model in the request handler
})
This difference causes incompatibility between Workers and Node.js environments. This project aims to solve that issue by providing a Node.js-like way to handle environment variables and initialize client libraries.
lazyenv
is universal, you can use same code in Node.js and Cloudflare Workers environment.
Make sure to set compatibility_flags = [ "nodejs_compat" ]
in wrangler.toml
.
compatibility_flags = [ "nodejs_compat" ]
Then, in your code, you can use lazyEnv
to lazily initialize client libraries.
const app = new Hono<{ Bindings: Env }>()
// 1. First, create an instance of `createEnvStore`.
export const env = createEnvStore<Env>();
app.use('*', (c, next) => {
// 2. Call `withEnv` before using `lazyEnv`.
// It’s recommended to do this in a middleware that catches all requests.
return env.withEnv(c.env, next)
})
// 3. Retrieve the top-level object that requires environment variables.
// The initializer passed to `lazyEnv` will be called only once, the first time it’s accessed.
const model = env.lazyEnv(() => google("gemini-1.5-flash"))
// => LanguageModelV1
app.get('/', async (c) => {
const result = await generateText({
// 4. You can use the instance just like a normal object.
model,
prompt: 'What is 2+8?',
})
return c.text(`result: ${result.text}`)
})
export default app
MIT