Streaming encryption is now available in browser-file-crypto.

Encrypt large files in the browser without worrying about memory. Streaming encryption has been added to browser-file-crypto v1.1.

Mingyu Lee
Mingyu Lee
January 9, 2026
3min read
Streaming encryption is now available in browser-file-crypto.

Earlier this month, when we open-sourced browser-file-crypto, we mentioned that we were "planning to add streaming encryption." That feature has now landed in v1.1.


Why did we need streaming encryption?

The original approach loaded the entire file into memory for encryption. Encrypt a 500MB file, and you're using 500MB+ of memory. That's fine for small files, but GB-sized files can crash the browser tab.

At TimeFile, we support uploads of tens to hundreds of gigabytes, so we ran into this problem firsthand. If you wanted to use secure sharing, you had to encrypt the file—but for large files, encryption simply wasn't possible.

The solution is to process files in chunks. By loading and encrypting just 64KB at a time, memory usage stays constant regardless of file size.

Memory usage comparison
The original approach uses memory proportional to file size. Streaming uses only the chunk size (64KB).

What's new?

Streaming encrypt/decrypt functions

Encrypt GB-sized files without worrying about memory.

TypeScript
1import { encryptFileStream, decryptFileStream } from '@time-file/browser-file-crypto';
2
3const encrypted = await encryptFileStream(largeFile, {
4 password: 'secret',
5 chunkSize: 64 * 1024, // default: 64KB
6 onProgress: ({ processedBytes, totalBytes, progress }) => {
7 console.log(`${progress}% complete`);
8 }
9});

Automatically picks the best approach based on file size. Small files use the original method (faster), large files use streaming (memory efficient).

TypeScript
1import { encryptFileAuto } from '@time-file/browser-file-crypto';
2
3const encrypted = await encryptFileAuto(file, {
4 password: 'secret',
5 autoStreaming: true,
6 streamingThreshold: 100 * 1024 * 1024 // 100MB (default)
7});
8// Under 100MB: original method (faster)
9// Over 100MB: streaming method (memory efficient)

Streaming download + decryption

Download and decrypt large files simultaneously.

TypeScript
1import { downloadAndDecryptStream } from '@time-file/browser-file-crypto';
2
3await downloadAndDecryptStream(url, {
4 fileName: 'large-file.zip',
5 password: 'secret',
6 onProgress: ({ phase, processedBytes }) => {
7 // phase: 'downloading' | 'decrypting' | 'complete'
8 }
9});

Backward compatibility

  • decryptFile() automatically detects the streaming format
  • Decrypt streaming-encrypted files without changing existing code
  • getEncryptionType() now returns 'password-stream' and 'keyfile-stream'

How TimeFile uses this

At TimeFile, we control the streaming feature via a Feature Flag. Our secure sharing uses encryptFileAuto with autoStreaming: true to handle large files automatically. This means even 100GB files can now be encrypted in the browser. Users just upload — they don't have to think about file size.


Technical details

Streaming file format

We use new markers to distinguish from the original format.

  • 0x11: Password-based streaming (34-byte header)
  • 0x12: Keyfile-based streaming (18-byte header)
Streaming file format structure
Streaming encryption appends consecutive chunks after the header.

Per-chunk authentication

Each 64KB chunk gets its own AES-GCM authentication tag (16 bytes).

  • Corruption in any part of the file is immediately detected
  • Integrity can be verified before decrypting the entire file
  • First chunk failure → INVALID_PASSWORD or INVALID_KEYFILE
  • Later chunk failure → DECRYPTION_FAILED (data corruption)

IV derivation

Each chunk must use a unique IV (Initialization Vector) to maintain security. AES-GCM must never reuse the same IV with the same key.

Plain Text
1chunk_iv = base_iv XOR chunk_index
  • base_iv: 12-byte random value stored in the header
  • chunk_index: 0, 1, 2, 3, ...
  • XOR generates a different IV for each chunk

Browser support

Streaming encryption uses the TransformStream API.

  • Chrome 67+
  • Firefox 102+
  • Safari 14.1+
  • Edge 79+

Most browsers released after 2020 are supported, and it works in Node.js 18+ as well.


How to update

npm
Bash
1npm install @time-file/browser-file-crypto@latest
pnpm
Bash
1pnpm add @time-file/browser-file-crypto@latest

What's next

We're considering Web Worker support. Currently, encryption runs on the main thread, so the UI can freeze momentarily when processing large files.


- npm: https://www.npmjs.com/package/@time-file/browser-file-crypto - GitHub: https://github.com/Time-File/browser-file-crypto - Streaming docs: docs/streaming.md Feedback and bug reports are welcome on GitHub Issues.


Footer