Glitch Node.js Projects: Using .env for Secrets and .data for Persistent Files
In a Glitch Node.js project, keep secrets in .env and durable files under .data. This guide covers the mechanism, restart and remix boundaries, and when to switch to external storage.
13 Jun 2026, 18:30 UTC

The short answer
In a Glitch Node.js project, treat the project tree as deployable code, not durable storage. Put secrets in the .env file and read them through process.env. Put generated or uploaded files under .data/ so they survive restarts. Everything else—your source files, package.json, public assets—should be considered part of the deployable application.
How the project model works
Glitch runs your Node.js application from the files in the project. At startup, the platform injects values from .env into the process environment, so your code can access them via process.env. The .data directory is the conventional path for runtime data that should persist across container restarts. The rest of the project tree is synced and redeployed when you edit it, which makes it a poor place for files that change at runtime.
Assumption: This guide describes the classic Glitch Node.js project model. Because the platform's hosting, pricing, and resource limits have evolved, treat the specifics below as a starting point and verify them against your current project dashboard and documentation.
Reading secrets from .env
Store configuration values such as API keys or session secrets in .env at the project root. In your application code, read them from process.env. Avoid hard-coding fallback secrets in production paths.
// server.js (or your app entry point)
const path = require('path');
const fs = require('fs');
// Read a secret from the environment.
// Use a clearly non-production fallback only for local development.
const sessionSecret = process.env.SESSION_SECRET || 'dev-only-insecure';
// Optional: log presence, never the value.
console.log('SESSION_SECRET present:', Boolean(process.env.SESSION_SECRET));
const dataDir = path.join(__dirname, '.data', 'uploads');
fs.mkdirSync(dataDir, { recursive: true });
In the .env file itself, keep one key-value pair per line:
SESSION_SECRET=replace-me
Because .env is security-sensitive, do not commit it to version control if you also maintain a Git repository, and test with dummy values before relying on real credentials.
Persisting files under .data
When your app needs to save a file—an uploaded image, a generated report, a small cache—write it beneath .data/. The example above creates .data/uploads at startup. A request handler might then save an incoming file to that directory. Because .data is intended to hold runtime data, the platform excludes it when another user remixes the project, which prevents probes and user files from leaking into copies.
Limits and when to use external services
Small hosted Node.js projects are a poor fit for large binaries, high-write databases, or always-on workloads. The project filesystem is not a general-purpose backup or a high-performance storage layer.
- Relational data: Prefer an external managed database. Writing frequently to a local SQLite file under
.datacan hit write limits or lose data if the underlying volume is reset. - Large files: Use object storage for images, videos, or archives. The project environment is not designed to serve or store large media libraries.
- Always-on processes: If your app must run continuously without sleeping, a small hosted project may not be the right tier. Verify current sleep and resource behavior in the dashboard.
- Concurrent writes: Do not assume multiple instances can safely write to the same
.datapath. Use a shared external store when coordination is required.
Common mistakes
- Writing temporary files to the project root instead of
.data/, which can pollute the deployable tree or be lost on redeploy. - Committing
.envto source control. Add it to.gitignoreif you use Git. - Treating
.dataas a backup. It holds runtime state, not a disaster-recovery copy. - Relying on in-memory state—variables, caches, or singleton connections—to survive a restart. Restart the process and assume memory is cleared.
- Using
.datafor concurrent writes from multiple instances without an external lock or database.
Verifying behavior in a disposable project
Because Glitch's hosting details, free-tier limits, and pricing have changed over time, confirm the current behavior in your own dashboard before relying on it. Use a disposable project with dummy values.
- Create a new project and add
PROBE=1to.env. - In your entry point, log
Boolean(process.env.PROBE)at startup. Restart the app from the dashboard and confirm the value staystrue. - From the running app, write a file to
.data/probe.txtand read it back. Restart again and read it once more to distinguish persistence from a warm cache. - Remix the project into a disposable copy. Inspect the copy for
.data/probe.txtand the.envvalue to confirm the remix boundary. - Check the project dashboard logs and current help or pricing pages for sleep behavior, resource limits, and storage rules.
If the probe file disappears after a restart, or the remixed copy contains your .data contents, adjust your storage strategy before deploying real user data.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.