npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@varlock/expo-integration

v1.1.0

Published

Expo/React Native Babel plugin to use varlock for .env file loading - adds validation, type-safety, and extra security features

Readme

@varlock/expo-integration

This package helps you integrate varlock into an Expo / React Native project.

It provides a Babel plugin for compile-time replacement of ENV.xxx references, and a Metro config wrapper that initializes the ENV proxy at runtime for server routes.

Compared to the default Expo behavior, this package provides:

  • Validation of your env vars against your .env.schema
  • Optional declarative loading of env var values via plugins
  • Type-generation and type-safe env var access with built-in docs
  • Redaction of sensitive values from application logs
  • Leak detection and prevention at build time (sensitive values are never inlined into your bundle)
  • More flexible multi-env handling

See our docs site for complete installation and usage instructions.

Installation

npm install --save-dev @varlock/expo-integration varlock
# or
yarn add --dev @varlock/expo-integration varlock
# or
bun add --dev @varlock/expo-integration varlock

Setup

1. Babel plugin

Add the Babel plugin to your babel.config.js:

module.exports = {
  presets: ['babel-preset-expo'],
  plugins: [
    require('@varlock/expo-integration/babel-plugin'),
  ],
};

This handles compile-time replacement of non-sensitive ENV.xxx references with their resolved values, similar to how Vite/webpack replace import.meta.env.xxx or process.env.xxx.

2. Metro config

Wrap your Metro config with withVarlockMetroConfig:

// metro.config.js
const { getDefaultConfig } = require('expo/metro-config');
const { withVarlockMetroConfig } = require('@varlock/expo-integration/metro-config');

const config = getDefaultConfig(__dirname);

module.exports = withVarlockMetroConfig(config);

This wrapper automatically:

  • Installs a custom resolver so that import { ENV } from 'varlock/env' works (Metro doesn't support package.json "exports" subpaths by default).
  • Initializes the varlock ENV proxy in the main Metro process so that sensitive values are available at runtime in Expo Router API routes (+api files).

Why is this needed? Metro forks worker processes for Babel transforms. The Babel plugin runs in those workers, but server routes are evaluated in the main Metro process. The Metro config wrapper ensures the environment is initialized in the correct process.

Usage

Import and use ENV in your code:

import { ENV } from 'varlock/env';

// Non-sensitive — replaced at compile time
const apiUrl = ENV.API_URL;

In server routes (+api files), both sensitive and non-sensitive values are accessible:

// app/secret+api.ts
import { ENV } from 'varlock/env';

export function GET() {
  // Sensitive values work at runtime in server routes
  const key = ENV.SECRET_KEY;
  return Response.json({ authorized: !!key });
}

How it works

  1. When Metro starts, withVarlockMetroConfig calls varlock load to resolve all environment variables and initializes the ENV proxy in the main process.
  2. The Babel plugin runs in Metro's worker processes and replaces non-sensitive ENV.xxx member expressions with their resolved literal values at compile time.
  3. Sensitive vars remain as ENV.xxx references in the compiled code. In +api server routes they resolve at runtime via the proxy. In native code they throw.

Sensitive values

Values marked with @sensitive in your .env.schema are never inlined into the JavaScript bundle. This prevents secrets from being embedded in code that ships to user devices.

In native code (client)

Sensitive values are not available in native app code. React Native apps run entirely on the device — there is no server to keep secrets safe. Accessing a sensitive value in native code will throw at runtime.

The Babel plugin also emits a build-time warning when it detects a sensitive ENV.xxx reference in a non-server file, so you can catch these issues before they reach production.

If you need a value in native code, reconsider whether it should be marked @sensitive. API keys for public services (e.g. a Maps API key) are typically non-sensitive and can be safely inlined.

In server routes (+api files)

Sensitive values are accessible at runtime via the ENV proxy in Expo Router API routes. These files run server-side in the Metro process where withVarlockMetroConfig has initialized the environment.

Note: Expo Router pages are universal — they render on both server (SSR) and client. This means you cannot access sensitive values directly in page components like you can in Next.js Server Components. Use +api server routes for any logic that requires secrets.

Security

  • Sensitive values (marked @sensitive) are never statically inlined into the bundle.
  • patchGlobalConsole() is called automatically to redact sensitive values from logs.
  • A build-time warning is emitted when sensitive values are referenced in native (non-server) code.
  • Accessing a sensitive value in client code throws at runtime, preventing accidental secret exposure.