Back to Essays
#web-development#minimalism#retro-computing

1.44 MB is Enough: Floppy Disks as Analog Computing

A technical exploration of how modern browser APIs and floppy disks enable a renaissance of physical, portable computing—combining web technologies with retro media for apps you truly own

1.44 MB is Enough: Floppy Disks as Analog Computing

There's something magical about physical media. You can hold it. Drop it in a drawer. Lend it to a friend. Unlike the cloud—ephemeral, contingent, surveilled—a floppy disk is yours.

What if we brought that tangibility back to web development? What if we built apps small enough to fit on a 1.44 MB floppy disk, complete with a simple data store that persists across sessions?

The Constraint

A standard 3.5" floppy disk holds 1,474,560 bytes. That's the canvas we get to work with.

In this space, you could fit:

  • A complete HTML/CSS/JS application (~50-200 KB)
  • A data.json file for persistence (~1 MB+)
  • Images, if you're clever about compression

The app lives on the disk. You mount it. You work. You eject it. The entire computing experience comes with you, physically, in your pocket.

Why This Matters

Physical Permanence

Cloud services shut down. Companies get acquired. Terms of service change. But a floppy disk? It's yours. Twenty years from now, if you can find a USB floppy drive, your data is still there.

There's something deeply satisfying about computing that exists in physical space. You're not renting server time. You're not hoping your free tier doesn't expire. You're just... computing.

Constraint-Driven Design

Working within 1.44 MB is a creative challenge. It's like writing a haiku or composing a three-minute pop song—the limitation becomes the art form.

When you have 1.44 MB total, every byte matters. You think about:

  • What's essential to this experience?
  • How can I make this work elegant and small?
  • What's the most efficient way to represent this data?

These constraints don't limit you—they liberate you. They force clarity. They demand intentionality. It's a puzzle to solve, and solving it feels great.

Why Not USB Sticks or Cloud Storage?

You absolutely could do this with USB sticks or cloud storage! And you should, if that fits your needs. But floppy disks have unique charm:

The Retro Aesthetic: There's something delightful about the tactile experience. The satisfying click. The label you write with a pen. It's computing you can feel.

The Constraint Game: 1.44 MB is just small enough to be challenging, but just large enough to be useful. It's the perfect constraint for creative problem-solving. A USB stick's 8GB doesn't have the same magic.

The Collectibility: Imagine a shelf of floppy disks, each one a different app. It's like a physical app drawer. You can gift them, trade them, or stumble upon one years later and rediscover what you made.

The Conversation Starter: When someone sees you pull out a floppy disk in 2025, they notice. It's interesting. It's different. It makes people curious about what you're building.

This same approach works beautifully with other retro media—Zip disks, CDs, even old SD cards. Each medium has its own character and constraints. This is just a love letter to one particularly endearing format that refuses to die.

The Technical Details

The App Diskette Architecture

This is where it gets interesting. Modern browsers give us two distinct approaches to data persistence, each with their own tradeoffs:

Approach 1: True Portability (File-Based) The disk itself contains everything. A data.json file sits alongside your HTML/CSS/JS. You manually load and save this file using the browser's File System Access API or simple file upload/download. The data lives on the physical medium.

Approach 2: Browser-Backed Hybrid The app on the disk uses browser APIs (IndexedDB, localStorage) to persist data in the browser's storage. The disk contains only the app code. Data stays with the browser, not the disk.

The beauty? You can build apps that support both modes.

Data Persistence Strategies

The Pure Approach: File-Based Storage

The simplest approach: a data.json file on the disk. Your app reads it on load, writes it on save. No database. No backend. Just the filesystem.

JSON
{
  "notes": [
    {
      "id": 1696723200000,
      "content": "First note on my floppy disk!",
      "timestamp": "2025-10-07T12:00:00.000Z"
    }
  ],
  "version": "1.0"
}

Limitations:

  • Browsers can't directly write to the floppy due to security restrictions
  • Users must manually export/import their data
  • File operations require user interaction (download/upload)

Clever Workarounds:

JAVASCRIPT
// Auto-save by triggering downloads
function saveToFloppy(data) {
  const blob = new Blob([JSON.stringify(data, null, 2)],
    { type: 'application/json' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = 'data.json';
  a.click();
  URL.revokeObjectURL(url);
}

// Load data from disk
function loadFromFloppy() {
  const input = document.createElement('input');
  input.type = 'file';
  input.accept = 'application/json';
  input.onchange = (e) => {
    const file = e.target.files[0];
    const reader = new FileReader();
    reader.onload = (event) => {
      const data = JSON.parse(event.target.result);
      // Use the data in your app
    };
    reader.readAsText(file);
  };
  input.click();
}

The Hybrid Approach: Browser APIs

Modern browsers are surprisingly powerful local databases. Here's what we can leverage:

IndexedDB: Store megabytes of structured data

  • Complex queries and indexes
  • Stores objects directly (no JSON serialization)
  • Can handle binary data (images, audio)

localStorage: Simple key-value storage

  • ~10 MB in most browsers
  • Synchronous and easy to use
  • Perfect for settings and small datasets

Cache API: Store entire network responses

  • Originally for PWAs, but perfect for floppy disk apps
  • Pre-cache external resources
  • Work offline seamlessly
JAVASCRIPT
// Hybrid storage system
class FloppyStorage {
  constructor() {
    this.prefersDisk = localStorage.getItem('storage-mode') === 'disk';
  }

  async save(data) {
    if (this.prefersDisk) {
      // Prompt user to save to floppy
      this.downloadJSON(data, 'data.json');
    } else {
      // Save to browser storage
      await this.saveToDB(data);
    }
  }

  async load() {
    if (this.prefersDisk) {
      // Prompt user to load from floppy
      return await this.uploadJSON();
    } else {
      // Load from browser storage
      return await this.loadFromDB();
    }
  }
}

Overcoming Browser Limitations

The CORS Problem

Want to fetch data from external APIs? CORS will block you. But here's where it gets clever:

Solution 1: Embedded Proxy Server (Node.js) Include a tiny Node.js proxy server on the floppy disk. It's just a few KB:

JAVASCRIPT
// proxy.js (~3 KB)
const http = require('http');
const https = require('https');

http.createServer((req, res) => {
  res.setHeader('Access-Control-Allow-Origin', '*');
  const url = req.url.slice(1); // Remove leading /
  https.get(url, (apiRes) => {
    apiRes.pipe(res);
  });
}).listen(8080);

Users run node proxy.js from the floppy, and your app fetches through http://localhost:8080/.

Solution 2: Public CORS Proxies Cache the URLs of free CORS proxies. Not as portable, but no setup required:

JAVASCRIPT
const CORS_PROXIES = [
  'https://corsproxy.io/?',
  'https://api.allorigins.win/raw?url='
];

async function fetchWithCORS(url) {
  for (const proxy of CORS_PROXIES) {
    try {
      const res = await fetch(proxy + encodeURIComponent(url));
      if (res.ok) return res;
    } catch (e) { continue; }
  }
  throw new Error('All proxies failed');
}

Solution 3: Server-Sent Events for Streaming For real-time data, use SSE. It's one-way, but perfect for notifications, updates, or logs:

JAVASCRIPT
const eventSource = new EventSource('http://localhost:8080/stream');
eventSource.onmessage = (event) => {
  console.log('New data:', event.data);
};

The File Size Constraint

1.44 MB goes fast. Here's how to maximize it:

Minification: Use a tiny minifier script on the floppy itself:

JAVASCRIPT
// minify.js (~2 KB)
const fs = require('fs');
const code = fs.readFileSync('app.js', 'utf8');
const minified = code
  .replace(/\/\*[\s\S]*?\*\//g, '') // Remove comments
  .replace(/\s+/g, ' ')              // Collapse whitespace
  .trim();
fs.writeFileSync('app.min.js', minified);

Compression: Use gzip encoding for JSON data:

JAVASCRIPT
// Store compressed data
const compressed = pako.gzip(JSON.stringify(data));
localStorage.setItem('data', btoa(String.fromCharCode(...compressed)));

// Decompress on load
const bytes = atob(localStorage.getItem('data')).split('').map(c => c.charCodeAt(0));
const data = JSON.parse(pako.ungzip(bytes, { to: 'string' }));

SVG over PNG: Vector graphics are tiny and scale perfectly:

HTML
<!-- 500 byte SVG icon instead of 5 KB PNG -->
<svg width="24" height="24" viewBox="0 0 24 24">
  <path d="M3 3h18v18H3z"/>
</svg>

File Structure

/floppy-disk/
├── index.html       (~10 KB)
├── style.css        (~5 KB)
├── app.js           (~35 KB - includes hybrid storage)
├── proxy.js         (~3 KB - optional Node.js CORS proxy)
├── minify.js        (~2 KB - optional build tool)
├── data.json        (~1.4 MB available)
└── README.txt       (~1 KB - setup instructions)

What You Can Build

Note-taking apps: Store thousands of plain text notes Todo lists: Simple task management Personal wikis: Linked markdown notes Game saves: Perfect for browser-based games Password managers: Encrypted JSON (with careful implementation) Pocket databases: Key-value stores for personal data

The App Diskette Renaissance

Imagine a world where floppy disks become the new "app store." Not metaphorically—literally. Physical diskettes you can buy, trade, or gift. Each one contains a complete, self-contained application.

Advanced Use Cases

Collaborative Documents Two people with the same app diskette can exchange data.json files. No cloud sync. No accounts. Just pass a USB stick.

JAVASCRIPT
// Export data for sharing
function exportForSharing() {
  const data = JSON.stringify({
    notes: myNotes,
    sharedBy: 'Alice',
    timestamp: Date.now()
  });
  // Download or copy to another floppy
  saveToFloppy(data);
}

Encrypted Personal Vaults Use the Web Crypto API for client-side encryption:

JAVASCRIPT
// Encrypt data before saving to disk
async function encryptData(data, password) {
  const encoder = new TextEncoder();
  const dataBytes = encoder.encode(JSON.stringify(data));

  // Derive key from password
  const keyMaterial = await crypto.subtle.importKey(
    'raw',
    encoder.encode(password),
    'PBKDF2',
    false,
    ['deriveBits', 'deriveKey']
  );

  const key = await crypto.subtle.deriveKey(
    { name: 'PBKDF2', salt: encoder.encode('salt'), iterations: 100000, hash: 'SHA-256' },
    keyMaterial,
    { name: 'AES-GCM', length: 256 },
    false,
    ['encrypt']
  );

  const iv = crypto.getRandomValues(new Uint8Array(12));
  const encrypted = await crypto.subtle.encrypt(
    { name: 'AES-GCM', iv },
    key,
    dataBytes
  );

  return { encrypted: Array.from(new Uint8Array(encrypted)), iv: Array.from(iv) };
}

Your password manager, tax documents, or personal journal—encrypted and stored on a physical disk you control.

Offline-First Web Apps Service Workers let floppy disk apps work completely offline:

JAVASCRIPT
// sw.js - Service Worker on the floppy
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open('floppy-v1').then((cache) => {
      return cache.addAll([
        './index.html',
        './style.css',
        './app.js'
      ]);
    })
  );
});

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request).then((response) => {
      return response || fetch(event.request);
    })
  );
});

The floppy becomes a bootable web app that works anywhere, even without internet.

Micro-Databases Build a queryable database that fits on a floppy:

JAVASCRIPT
// Simple in-memory database with indexing
class FloppyDB {
  constructor(data) {
    this.records = data;
    this.indexes = {};
    this.buildIndexes();
  }

  buildIndexes() {
    this.records.forEach((record, i) => {
      Object.keys(record).forEach(key => {
        if (!this.indexes[key]) this.indexes[key] = {};
        this.indexes[key][record[key]] = i;
      });
    });
  }

  find(query) {
    const [key, value] = Object.entries(query)[0];
    const idx = this.indexes[key][value];
    return idx !== undefined ? this.records[idx] : null;
  }
}

// Use it
const db = new FloppyDB(JSON.parse(loadFromFloppy()));
const user = db.find({ email: 'alice@example.com' });

Store 10,000+ records, indexed and queryable in milliseconds.

The Analog Experience

Here's the workflow:

  1. Insert floppy disk into USB drive
  2. Open index.html in your browser
  3. Work with your app—it reads/writes to data.json or browser storage
  4. Optionally: Run node proxy.js for API access
  5. Eject disk when done
  6. Take it with you

The physicality changes how you think about computing. This isn't just another browser tab. It's a thing. It has weight. It has presence.

You could have different disks for different projects:

  • Personal journal (Disk 1) - File-based storage for true portability
  • Work notes (Disk 2) - Browser-backed for searchability
  • Recipe collection (Disk 3) - With embedded images
  • API client (Disk 4) - Includes proxy.js for external data
  • Password manager (Disk 5) - Encrypted vault
  • Game progress (Disk 6) - Save states and high scores

Each one is a complete, self-contained computing environment.

Networking Between Diskettes

Here's where it gets wild. Multiple floppy disk apps can communicate through the browser:

Broadcast Channel API:

JAVASCRIPT
// Disk 1: Todo app
const channel = new BroadcastChannel('floppy-network');
channel.postMessage({ type: 'task-complete', task: 'Write blog post' });

// Disk 2: Time tracker app (running in another tab)
const channel = new BroadcastChannel('floppy-network');
channel.onmessage = (event) => {
  if (event.data.type === 'task-complete') {
    stopTimer(event.data.task);
  }
};

Different floppy disk apps, running in separate tabs, can communicate and coordinate. Each disk is independent, but they can work together.

Web Sockets for Multi-User Apps: Include a tiny WebSocket server on the disk:

JAVASCRIPT
// ws-server.js (~4 KB)
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8081 });

const clients = new Set();

wss.on('connection', (ws) => {
  clients.add(ws);
  ws.on('message', (message) => {
    // Broadcast to all clients
    clients.forEach(client => {
      if (client !== ws && client.readyState === WebSocket.OPEN) {
        client.send(message);
      }
    });
  });
  ws.on('close', () => clients.delete(ws));
});

Now your floppy disk app supports real-time collaboration on the local network. Multiple people can run the same diskette app and sync changes live.

The Technical Imagination Space

What else becomes possible?

Floppy Disk Package Manager: A diskette that installs other diskettes Bootable Dev Environment: HTML/CSS/JS editor that saves to the floppy Portable Game Engine: Write games that run directly from the disk Medical Records: HIPAA-compliant patient data on physical media Voting Systems: Verifiable, auditable, air-gapped election software Academic Archives: Research data that outlives institutional servers

The constraint forces creativity. The physicality demands intentionality. The simplicity enables longevity.

Real-World Limitations and Workarounds

Let's be honest about the challenges:

Problem: Browser Security Restrictions Browsers prevent direct filesystem access by design. You can't write to the floppy automatically.

Workaround: Use the File System Access API (Chrome/Edge) for near-direct access, or fall back to download prompts. The UX isn't perfect, but it works:

JAVASCRIPT
// Modern approach with File System Access API
async function saveWithFileSystem(data) {
  try {
    const handle = await window.showSaveFilePicker({
      suggestedName: 'data.json',
      types: [{
        description: 'JSON Files',
        accept: { 'application/json': ['.json'] }
      }]
    });
    const writable = await handle.createWritable();
    await writable.write(JSON.stringify(data, null, 2));
    await writable.close();
  } catch (err) {
    // User cancelled or API not supported
    fallbackToDownload(data);
  }
}

Problem: Floppy Disk Reliability Magnetic media degrades. Floppies fail. That 20-year archive might not survive.

Workaround: Accept it as part of the medium's character, or:

  • Keep multiple copies across several disks
  • Use the browser-backed approach for critical data
  • Periodically "refresh" old disks by copying to new ones
  • Use the floppy as a transport mechanism, not long-term storage

Problem: Limited Space 1.44 MB fills up fast with modern expectations.

Workaround: This is a feature, not a bug. It forces discipline:

  • Plain text over rich text
  • SVG over raster images
  • Compression for everything
  • Smart data structures (use arrays of arrays instead of objects to reduce key overhead)
JAVASCRIPT
// Space-efficient data format
// Bad: 125 bytes for 2 records
[
  { "id": 1, "name": "Alice", "email": "alice@example.com" },
  { "id": 2, "name": "Bob", "email": "bob@example.com" }
]

// Good: 85 bytes for same data
{
  "keys": ["id", "name", "email"],
  "data": [
    [1, "Alice", "alice@example.com"],
    [2, "Bob", "bob@example.com"]
  ]
}

Problem: No True Portability Between Computers Browser storage is local. Your IndexedDB data doesn't travel with the floppy.

Workaround: Build dual-mode apps that let users choose their tradeoff:

  • Portability mode: Data on disk, manual save/load
  • Performance mode: Data in browser, automatic sync

Or use a hybrid approach:

JAVASCRIPT
// Sync browser data to disk before closing
window.addEventListener('beforeunload', async () => {
  const data = await getAllDataFromIndexedDB();
  localStorage.setItem('pending-export', JSON.stringify(data));
  // Prompt user to save if they haven't recently
});

Problem: The Proxy Server Requirement For CORS workarounds, users need to run Node.js. That's a barrier.

Workaround:

  • Include a pre-compiled binary (using pkg or similar)
  • Provide a web-based version with limited features
  • Use public CORS proxies for non-sensitive data
  • Design apps that don't need external APIs

The limitations are real, but they're also part of the point. This isn't meant to replace modern web apps. It's an exploration of what computing looks like when you prioritize ownership, simplicity, and physicality over convenience and cloud dependence.

Modern Web, Retro Medium

This isn't nostalgia—it's discovery. What happens when you combine the power of modern web technologies with the charm of retro media?

HTML/CSS/JS has matured into an incredibly capable platform. Modern browser APIs give us databases, encryption, offline storage, real-time communication—all the tools we need to build rich, interactive applications. And we can fit it all on a floppy disk.

The web is portable, linkable, and universal. Files are simple. Standards are stable. When you combine these strengths with physical media, you get something wonderfully tangible: your code, your data, your medium.

It's the best of both worlds—the capabilities of modern web development with the permanence and personality of physical computing.

Building Your Own

Want to try it? Here's what you need:

Hardware:

  1. A USB floppy drive (~$15-30 online)
  2. Blank floppy disks (surprisingly still available)

Software Stack (all optional, mix and match): 3. HTML/CSS/JS app (vanilla, no frameworks needed) 4. Data format: JSON, CSV, or plain text 5. Node.js (optional, for proxy server or build tools) 6. Browser APIs: IndexedDB, localStorage, Service Workers, Web Crypto

Getting Started:

Start simple. Build a note-taking app. A todo list. Something that fits in 50 KB of code. Here's a minimal example:

HTML
<!DOCTYPE html>
<html>
<head>
  <title>Floppy Notes</title>
  <style>
    body { font-family: monospace; max-width: 600px; margin: 50px auto; }
    textarea { width: 100%; height: 300px; }
    button { padding: 10px 20px; margin: 5px; }
  </style>
</head>
<body>
  <h1>Floppy Notes</h1>
  <textarea id="editor"></textarea>
  <button onclick="save()">Save to Disk</button>
  <button onclick="load()">Load from Disk</button>

  <script>
    function save() {
      const text = document.getElementById('editor').value;
      const blob = new Blob([text], { type: 'text/plain' });
      const a = document.createElement('a');
      a.href = URL.createObjectURL(blob);
      a.download = 'notes.txt';
      a.click();
    }

    function load() {
      const input = document.createElement('input');
      input.type = 'file';
      input.accept = 'text/plain';
      input.onchange = (e) => {
        const file = e.target.files[0];
        const reader = new FileReader();
        reader.onload = (event) => {
          document.getElementById('editor').value = event.target.result;
        };
        reader.readAsText(file);
      };
      input.click();
    }

    // Auto-load from localStorage on startup
    window.onload = () => {
      const saved = localStorage.getItem('notes');
      if (saved) document.getElementById('editor').value = saved;
    };

    // Auto-save to localStorage on change
    document.getElementById('editor').oninput = (e) => {
      localStorage.setItem('notes', e.target.value);
    };
  </script>
</body>
</html>

That's it. 1.5 KB. Works offline. Persists data. Fits on any floppy with room to spare.

Next Steps:

  1. Test it. Save to index.html on a floppy. Open it in a browser.
  2. Add features. Maybe a word count? Search functionality? Timestamps?
  3. Optimize space. Minify your code. Use SVG icons instead of PNGs.
  4. Add networking. Include proxy.js to fetch from external APIs.
  5. Share it. Give the diskette to a friend. Watch them use your app.

The beauty is that you're not deploying to servers. You're not configuring CI/CD. You're just... copying files to a disk. Computing at its most fundamental.

The Future of Analog Computing

This is an experiment in what computing could be. A philosophy that celebrates:

  • Ownership - It's yours, completely
  • Simplicity - No servers, no accounts, no complexity
  • Permanence - Physical media that outlasts services
  • Physicality - Computing you can hold and share

The cloud is amazing for what it does. Modern frameworks solve real problems. But there's room for other approaches too. Room for experiments that explore different tradeoffs.

Sometimes, 1.44 MB is enough. Sometimes, the constraint is the point. Sometimes, the joy is in seeing what you can build when you make something delightfully small and wonderfully tangible.

Try it with floppy disks. Try it with CDs. Try it with USB sticks. The medium doesn't matter as much as the mindset: what can we build that's simple, physical, and ours?

Inspiration and Further Reading

This exploration stands on the shoulders of others who've been thinking deeply about resilient, sustainable, and human-centered computing.

Hundred Rabbits has been pioneering low-power, offline-first software for years. Sailing the Pacific on a small boat, they've created an entire ecosystem of tools that work with minimal resources—from their Uxn virtual machine to their suite of creative applications. Their work proves that powerful software doesn't need to be heavy. When your power comes from solar panels and your internet is sporadic at best, you learn to build differently. Their philosophy of permacomputing—computing that could last for generations—deeply informs this floppy disk experiment.

Ink & Switch explores the future of computing through research on local-first software—applications that keep your data on your device, work offline by default, and sync peer-to-peer when connected. Their essay "Local-First Software: You Own Your Data, in Spite of the Cloud" articulates why ownership matters and how we can build software that respects users' autonomy. They've explored everything from CRDTs for conflict-free sync to malleable software that users can reshape to their needs.

Both groups ask similar questions: What if we built software that could last? What if apps worked offline by default? What if you truly owned your data and your tools?

Floppy disk computing is a playful answer to these questions. It's taking these serious ideas about resilience, ownership, and longevity, and exploring them through a deliberately retro lens. The medium might be whimsical, but the principles are sound.

If this post resonates with you, dive into their work. They're charting paths toward computing that's more sustainable, more human, and more enduring than what we often build today.


Want to see a working prototype? Check out the Floppy Notes app that fits entirely on a floppy disk.