Plain Text Will Outlive Us All

Contents
I have a folder of Markdown notes going back nine years that opens instantly in absolutely anything — a text editor, cat, a phone’s default notes app, a decade-old laptop I keep around for exactly this kind of archaeology. I also have a handful of files from roughly the same era saved out of applications that no longer exist, in formats whose only reliable reader was the application itself, and I cannot open most of them without real effort. The plain text has not degraded at all. The proprietary formats are, functionally, gone, even though the bytes are still sitting right there on disk.
That asymmetry is not an accident of which formats happened to get lucky. Plain text survives because it depends on almost nothing — no licensed codec, no vendor’s continued existence, no specific application version — while every richer format trades some of that independence for features, and features are exactly the things that stop being maintained once a product is discontinued or a company changes strategy.
What “plain text” actually guarantees you
A plain text file is, at the lowest level, a sequence of bytes with an agreed-upon character encoding and nothing else. There is no header describing a proprietary schema, no embedded binary blob only one application’s parser understands, no DRM, no dependency on a specific rendering engine to reconstruct what the content actually says. Reading it back only requires knowing the encoding, and for the overwhelming majority of plain text written in the last fifteen years, that encoding is UTF-8, which has become close enough to universal that assuming it by default is now the safe choice rather than the risky one.
This is not a claim that plain text is sufficient for everything — clearly it is not, and nobody is proposing you store a spreadsheet’s formula graph or a CAD model as a .txt file. It is a claim that for anything text-shaped — notes, configuration, documentation, structured data that fits a schema like YAML or JSON — the format’s simplicity is a durability feature, not a limitation you tolerate. I’ve made a version of this argument before about reaching for a boring text file over a database for small, low-concurrency needs; the longevity angle is the same argument from a different direction.
Why rich formats rot and text mostly doesn’t
A proprietary document format typically embeds three things plain text never has to worry about: a versioned binary schema that changes between application releases, features that depend on the specific rendering engine that shipped alongside the format (a particular font-substitution algorithm, a particular layout engine’s line-wrapping behaviour), and often outright vendor lock-in where opening the file at all requires a licence for software that may no longer be sold. Any one of those three is enough to turn “I have this file” into “I have these bytes and no working way to interpret them” within a decade, and formats that combine two or three of them rot faster than that.
Markdown, by contrast, was designed explicitly to degrade gracefully — a Markdown file with zero rendering support is still readable prose with a few stray asterisks and hash marks in it, because the format’s core idea was “make the plain text itself pleasant to read,” and the rendering is a convenience layered on top rather than a requirement for comprehension. YAML and JSON make the equivalent trade for structured data: opening a config file in a plain editor, with no YAML-aware tooling at all, still shows you a human-legible key-value structure, which is not true of a binary-serialized configuration blob from the equivalent enterprise product.
The encoding problem that actually still bites people
The place plain text’s promise breaks down in practice is character encoding mismatches, and it is worth understanding why rather than treating “just use UTF-8” as an incantation. A byte sequence has no encoding of its own — it is only ever a sequence of numbers until something decides which character set to interpret those numbers against. A file saved as Windows-1252 and opened assuming UTF-8, or vice versa, will “work” in the sense that some characters will render, and then quietly corrupt anything outside the 7-bit ASCII range that both encodings happen to agree on — accented letters, curly quotes, em dashes, anything a word processor’s autocorrect silently substituted in for you. This is the mechanism behind the classic “mojibake” garbage you see when a file with an em dash gets reinterpreted under the wrong encoding and turns into a string of unrelated symbols. I’ve gone into the full mechanics of how Unicode actually solved the encoding chaos that predated it, and the short version relevant here is: declare UTF-8 explicitly wherever a format allows it, and treat any tool that defaults to something else as a liability rather than a quirk to work around silently.
Line endings are the second, smaller version of the same category of problem. A file written with Windows-style CRLF line endings and processed by a tool expecting Unix-style LF alone will frequently “work” while silently appending an invisible carriage-return character to every line, which then breaks string comparisons, shell script parsing, or git diffs that suddenly show every line as changed even though nothing visible did. git config core.autocrlf exists specifically to manage this at the repository boundary, translating consistently on checkout and checkin rather than leaving it to chance, and is worth setting deliberately rather than discovering the hard way after a diff that should have been three lines shows three hundred.
Where plain text is the wrong tool
None of this is an argument for storing everything as text against its nature. A large binary blob — a photo, a database’s raw storage engine, anything genuinely non-textual — gains nothing from being forced into a text encoding, and doing so (base64-encoding an image into a JSON field, say) usually makes it larger and no more durable, since the outer text format’s durability does not transfer to bytes it is merely wrapping rather than actually representing. The right test is whether the content is conceptually text — words, structured key-value data, configuration a human might reasonably want to read directly — not whether you could technically force it into a text file.
Structured data at genuine scale is the other edge case worth naming: a text format like CSV or JSON Lines is a fine durability choice for a few thousand rows, but querying millions of records by scanning a text file linearly is a real performance problem a proper file format like Parquet, or a database’s own storage engine, solves correctly. Durability and query performance are different axes, and it is worth being honest about which one actually matters for a given dataset before defaulting to plain text out of principle.
Text is also the format version control actually understands
There is a compounding benefit to plain text that has nothing to do with longevity directly: every serious version control tool was built assuming line-oriented text, and the diffing, merging and blame tooling that makes Git genuinely useful only works well against that assumption. A binary document format changing between two commits gives you a diff that says, in effect, “this file changed,” with no meaningful indication of what changed or why, because there is no line-oriented structure for the diff algorithm to compare against. A Markdown file, a YAML config, a piece of source code changing between the same two commits gives you an exact, reviewable, line-by-line account of what changed, which is the entire value proposition of code review and configuration review alike.
That reviewability compounds across an entire homelab’s history. I keep my entire homelab’s configuration — reverse proxy rules, Compose files, Ansible playbooks, the actual content of this website — in Git for exactly this reason, and the ability to run git blame on a config file and see precisely when and why a particular line was added is a genuinely different category of debugging tool from “restore yesterday’s backup and diff the whole directory by eye,” which is what the equivalent process looks like for a binary format with no meaningful diff. That level of insight, understanding precisely why a change happened rather than merely that one did, compounds into a genuinely large practical advantage over the life of a project.
Greppability is underrated
The other quiet superpower of plain text is that every tool your operating system already has can search it, without needing to understand the format’s internal structure at all. grep, ripgrep, your editor’s find-in-files, a shell pipeline piping through awk or sed — all of them work identically well on a Markdown note, a YAML config, or a CSV export, because none of them need to know anything about the file’s structure beyond “it is a sequence of lines.” Searching a folder of proprietary documents for a phrase you vaguely remember writing three years ago, by contrast, depends entirely on whichever application produced them shipping a full-text search feature that actually indexes the content correctly, which is a much less reliable bet than “every text tool ever written already handles this.”
This matters more than it sounds like it should the moment your note-taking or configuration setup grows past what you can browse by folder structure alone. A homelab with forty services each configured slightly differently is only tractable to audit years later because grep -r "some_setting" . across the whole configuration tree returns every place that setting appears, in every file, instantly, with no dependency on a search index that might be stale or an application that might no longer exist to run the search inside.
Troubleshooting the practical failure modes
A file that displays correctly in one application and garbled in another is almost always an encoding mismatch, and the fix is to check explicitly rather than guess — file -i somefile.txt on Linux will report its best guess at the encoding, and reopening the file with that encoding forced, then re-saving explicitly as UTF-8, fixes it permanently rather than papering over the symptom in one viewer.
A git diff that shows every line of a file as changed when you believe you only edited one is almost always a line-ending or whitespace-normalisation mismatch, not a real content change — check git diff --stat for suspiciously large changed-line counts on a small edit, and check .gitattributes for a text=auto setting that may be silently renormalising line endings on checkout in a way that disagrees with what your editor is writing.
A YAML file that parses in one tool and throws a syntax error in another is very often a tab-versus-space indentation mismatch, since YAML’s spec requires spaces for indentation and many editors default to inserting tabs; configuring your editor to insert spaces for that file type specifically, rather than relying on a global tab setting, avoids the entire category of error.
A file that looks empty or truncated when opened in a plain editor but is clearly not zero bytes on disk is usually a byte-order mark or a null-byte issue from a tool that wrote UTF-16 rather than UTF-8, which some Windows-originated export tools still default to. hexdump -C somefile.txt | head will show you the raw bytes at the start of the file; a BOM appears as the specific three-byte sequence EF BB BF for UTF-8 or a two-byte pattern for UTF-16, and stripping it or re-saving explicitly in UTF-8 without a BOM resolves tools that choke on its presence, which is a surprising number of them given how old and settled the encoding itself is.
Is it worth defaulting to
For anything genuinely text-shaped — your notes, your configuration, your documentation, small structured datasets — yes, and the discipline is worth the minor inconvenience of occasionally wanting a feature a richer format would have given you for free. The proprietary alternative buys you formatting or tooling convenience today in exchange for a real risk that the file becomes unreadable, or readable only with real effort, in a decade. Plain text’s boring durability is the actual reason your notes from nine years ago still open today, while files from applications you have long since stopped using sit unopenable on the same disk.




