If you see "env" is not exported by "virtual:$env/static/private", check whether your code imports a generic env object from $env/static/private. In the documented SvelteKit 2.0.2 reproduction, that module does not export such an object: import the configured variable by its actual name instead. First check your SvelteKit version, because SvelteKit 3 uses a different environment-variable API.
Fix the “env” export error in SvelteKit 2
The issue report describes this error in a SvelteKit 2.0.2 reproduction. Its cause is an import of a generic env object, not a supported way to access all environment variables. Replace it with a named import for the variable you configured:
As an Amazon Associate I earn from qualifying purchases.
// Incorrect: $env/static/private does not export a generic `env` object
import { env } from '$env/static/private';
// Correct: import the configured variable by its actual name
import { DATABASE_URL } from '$env/static/private';
The name must match the variable available to the build. If the named import still fails, check its spelling, confirm that it is available in the build environment, and verify the installed SvelteKit version. The issue report establishes this specific failure; it does not show that every error described as a “destructuring” error has the same cause. SvelteKit issue #10469.
Check which SvelteKit environment API your project uses
The right import depends on the framework version. SvelteKit 3 deprecates the $env/... module family in favor of $app/env/private and $app/env/public. Its migration guidance introduces defineEnvVars for declaring variables. Before SvelteKit 3, the documented private-variable modules are $env/dynamic/private and $env/static/private. SvelteKit 3 migration guide.
#1 Best Overall
Do not copy an import from a different major version without checking the version installed in your project. The module name and variable declaration pattern have changed.
Choose static or dynamic values based on when they are needed
Static and dynamic describe when a value is selected. Private and public describe which code may access it. These are separate decisions: a private value is still sensitive if it is fixed into a build.
| Choice | When the value is selected | Where it may be used | Practical consequence |
|---|---|---|---|
| Dynamic private | At app runtime | Server-only code | A built app can use values supplied by its runtime environment, allowing configuration to vary between deployments. |
| Static private | At build time | Server-only code | The value is inlined into generated application code and fixed to that build; static values can also enable dead-code elimination. |
In SvelteKit 3, environment variables are dynamic by default: “their values are read when the app runs, rather than being fixed when it is built.” Svelte tutorial: private environment variables. In earlier versions, the choice is expressed by using the dynamic or static module.
Free tools Windows power users keep installed
One-click scans. No signup required.
Why a static private value can expose a secret
“Private” limits access to server-side code; it does not mean a value is safe to embed in a build. A static private value becomes part of that build’s generated output. Treat it as fixed build content, and use this approach only when fixing the value for that build is intentional and distribution of the build is controlled.
Rank #3
For credentials that should vary between deployments or rotate independently of a new build, use runtime or dynamic configuration instead. Keep private imports in server-only modules, and never pass secret values into browser-visible code or data.
Keep private imports inside the server boundary
Private environment modules are for server-only files, such as server route files and server hooks. A browser-facing module cannot import a private variable. The boundary also applies to the full import chain: importing a server module into client code can be unsafe even if the client appears to use only a harmless export from it. SvelteKit documentation: server-only modules.
Rank #4
When an import triggers a server-only restriction, inspect not just the file named in the error but also the modules it imports. Move secret access and other server-only logic into server-side files, and pass only data safe for the browser across the boundary.
Configure a private value in SvelteKit 3
The SvelteKit tutorial demonstrates declaring variables with defineEnvVars in src/env.js, then importing a private value from $app/env/private in a +page.server.js action. Ordinary private values are dynamic by default; the tutorial also shows opting a feature flag into static: true. Follow the current tutorial and migration guidance for the exact declaration and import syntax for your project version. Svelte tutorial: private environment variables.
Quick Recap
Best Value
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




