# How to Block Remote Model Downloads and Use Local Files Only in Production with Transformers.js

> Secure your production Transformers.js apps. Block remote model downloads and use local files only to prevent unauthorized access and improve performance. Learn how to configure.

- Repository: [Hugging Face/transformers.js](https://github.com/huggingface/transformers.js)
- Tags: best-practices
- Published: 2026-03-03

---

** Set `env.allowRemoteModels = false` before initializing any pipelines or models to globally block network requests, or pass `local_files_only: true` to individual constructors to enforce local-only asset loading for specific calls.**

Transformers.js loads model assets— ONNX weights, tokenizers, and config files—from the Hugging Face Hub by default. For secure production environments, air-gapped deployments, or CI/CD pipelines with strict egress rules, you must prevent automatic remote downloads and rely exclusively on pre-cached local files. The library implements this control through a global **environment object** exported from [`src/env.js`](https://github.com/huggingface/transformers.js/blob/main/src/env.js) and a resource loader in [`src/utils/hub.js`](https://github.com/huggingface/transformers.js/blob/main/src/utils/hub.js) that validates permissions before every network request.

## How the Download Flow Works

The asset loading mechanism follows a strict resolution order defined in [`src/utils/hub.js`](https://github.com/huggingface/transformers.js/blob/main/src/utils/hub.js) (lines 85-108). When you initialize a pipeline or model, the library first builds both local and remote paths via `buildResourcePaths()`. It then attempts to read from the local filesystem if `env.allowLocalModels` is enabled. Only if the file is missing and remote downloads are permitted will the loader construct a `fetch` request.

The guard logic works as follows:

1. Compute `localPath` and `remoteURL` for every required file.
2. Attempt to load from `localPath` when `env.allowLocalModels` is `true`.
3. If the file is missing **and** either `options.local_files_only` or `env.allowRemoteModels` is false, throw an error immediately.
4. Otherwise, fetch from `remoteURL`.

This ensures that no HTTP traffic is generated when local-only mode is active, as the check occurs before any network call is constructed.

## Method 1: Global Environment Configuration

The most reliable way to secure a production deployment is to disable remote downloads at the environment level. The `env` object exported from [`src/env.js`](https://github.com/huggingface/transformers.js/blob/main/src/env.js) contains the boolean property `allowRemoteModels` (default: `true`). Setting this to `false` affects every subsequent model, tokenizer, and pipeline instantiation.

Configure this once in your application entry point:

```javascript
import { env } from '@huggingface/transformers';

// Point to your pre-downloaded model directory
env.localModelPath = '/opt/models/';
// Block all remote network requests
env.allowRemoteModels = false;
// Ensure local files are checked first
env.allowLocalModels = true;

```

With these settings, any attempt to load a missing file will raise an error at [`src/utils/hub.js`](https://github.com/huggingface/transformers.js/blob/main/src/utils/hub.js) (lines 99-108) stating that `local_files_only=true` or `env.allowRemoteModels=false` and the file was not found locally. This fails fast during startup rather than attempting a network request at runtime.

## Method 2: Per-Call Local Files Only

For finer control, you can enforce local-only loading for specific components while allowing remote downloads elsewhere. Pass `local_files_only: true` in the options object when creating a pipeline, model, or tokenizer:

```javascript
import { pipeline } from '@huggingface/transformers';

const sentiment = await pipeline('sentiment-analysis', 'Xenova/distilbert-base-uncased-finetuned-sst-2-english', {
  local_files_only: true,  // Blocks remote download for this specific pipeline
});

```

This parameter propagates through to the `loadResourceFile` function in [`src/utils/hub.js`](https://github.com/huggingface/transformers.js/blob/main/src/utils/hub.js), triggering the same guard logic as the global flag but scoped to a single operation. This is useful when you have some models cached locally but need to fetch others dynamically during development.

## Production Deployment Workflow

Follow this three-step pattern to deploy transformers.js in offline or restricted environments:

### 1. Pre-Download Assets

Download all required model files during your build process or a one-off setup script. Ensure the directory contains the ONNX weights, [`config.json`](https://github.com/huggingface/transformers.js/blob/main/config.json), [`tokenizer.json`](https://github.com/huggingface/transformers.js/blob/main/tokenizer.json), and any additional preprocessing files.

### 2. Configure Environment Flags

In your production entry file, set the environment variables before any model initialization:

```javascript
import { env } from '@huggingface/transformers';

env.localModelPath = process.env.MODEL_DIR || '/models/';
env.allowRemoteModels = false;
env.allowLocalModels = true;

```

### 3. Initialize with Local Guarantees

When creating pipelines, optionally include the per-call safety net:

```javascript
const pipe = await pipeline('feature-extraction', {
  local_files_only: true,
});

```

## Complete Implementation Examples

### Node.js Production Server

```javascript
// server.js
import { env, pipeline } from '@huggingface/transformers';
import express from 'express';

// Lock configuration before any model loading
env.localModelPath = '/var/app/models';
env.allowRemoteModels = false;
env.allowLocalModels = true;

const app = express();

const ner = await pipeline('token-classification', {
  local_files_only: true,  // Additional safety layer
});

app.post('/analyze', async (req, res) => {
  const result = await ner(req.body.text);
  res.json(result);
});

app.listen(3000, () => console.log('Server running with local-only models'));

```

### Browser with Pre-Cached Models

```html
<script type="module">
  import { env, pipeline } from 'https://cdn.jsdelivr.net/npm/@huggingface/transformers@4.0.0-next.5';

  // Assume models are bundled in the service worker cache or /models/ directory
  env.allowRemoteModels = false;
  env.localModelPath = '/models/';

  const textGen = await pipeline('text-generation', {
    model: 'my-local-gpt-model',
    local_files_only: true,
  });

  const output = await textGen('The quick brown fox');
  console.log(output);
</script>

```

### CI/CD Pre-Download Script

```bash
#!/bin/bash

# download-models.mjs

import { env, pipeline } from '@huggingface/transformers';
import { mkdir } from 'fs/promises';

const MODEL_DIR = './cached-models';
await mkdir(MODEL_DIR, { recursive: true });

// Temporarily allow downloads to populate the cache
env.allowRemoteModels = true;
env.localModelPath = MODEL_DIR;

const pipe = await pipeline('sentiment-analysis');
// Warm up to trigger downloads
await pipe('warmup text');

console.log(`Models cached in ${MODEL_DIR}`);

# Commit the cached files, then set env.allowRemoteModels = false in production

```

## Summary

- **Global lock**: Set `env.allowRemoteModels = false` in [`src/env.js`](https://github.com/huggingface/transformers.js/blob/main/src/env.js) to block all remote requests for the entire application lifecycle.
- **Per-call control**: Pass `local_files_only: true` to any pipeline or model constructor to enforce local loading for specific instances.
- **Core implementation**: The guard logic resides in [`src/utils/hub.js`](https://github.com/huggingface/transformers.js/blob/main/src/utils/hub.js) (lines 85-108), which checks permissions before calling `fetch()` or `getFile()`.
- **Path resolution**: Use `env.localModelPath` to specify where pre-downloaded ONNX files and configs are stored (default: `/models/`).
- **Metadata blocking**: The `allowRemoteModels` flag is also respected in [`src/utils/model_registry/get_file_metadata.js`](https://github.com/huggingface/transformers.js/blob/main/src/utils/model_registry/get_file_metadata.js) (lines 98-99), preventing even HEAD requests for file metadata.

## Frequently Asked Questions

### Will changing `env.allowRemoteModels` affect already loaded models?

Yes. While existing model instances retain their weights, any subsequent file loading—such as lazy-loading decoder weights or fetching additional vocabulary files—will respect the current value of `env.allowRemoteModels`. Always set this flag at application startup before initializing any pipelines.

### What error does transformers.js throw when a file is missing in local-only mode?

The library throws a descriptive error from [`src/utils/hub.js`](https://github.com/huggingface/transformers.js/blob/main/src/utils/hub.js) stating: *"`local_files_only=true` or `env.allowRemoteModels=false` and file was not found locally"* followed by the missing file path. This allows you to catch configuration errors during deployment rather than at runtime.

### Can I use a custom directory structure for local models?

Yes. Set `env.localModelPath` to any absolute or relative path before loading models. The library expects the directory to contain subfolders matching the model ID structure (e.g., `Xenova/distilbert-base-uncased-finetuned-sst-2-english/`). The `buildResourcePaths()` function in [`src/utils/hub.js`](https://github.com/huggingface/transformers.js/blob/main/src/utils/hub.js) constructs full paths by joining `localModelPath` with the model identifier and filename.

### Does `local_files_only` block all network traffic from the library?

When enabled globally via `env.allowRemoteModels = false`, the library blocks all HTTP requests for model assets, tokenizer configs, and metadata lookups (as checked in [`get_file_metadata.js`](https://github.com/huggingface/transformers.js/blob/main/get_file_metadata.js)). However, this does not affect network calls made by your own application code or other dependencies—only transformers.js internal hub requests are gated.