CRLF vs LF vs CR: Text Line Endings Explained

CRLF, LF and CR are three conventions for marking where a line of text ends. LF is a single line feed character (U+000A), used by Linux, macOS and other Unix-like systems. CRLF is a carriage return (U+000D) followed by a line feed, used by Windows and required by several internet protocols. CR on its own was the line ending of classic Mac OS and is now rare.

All three look the same on screen: the next character simply starts a new line. The difference appears only when a program that expects one convention is given another, and then it appears as stray ^M marks, text squeezed onto one line, doubled blank lines, or a diff that claims every line has changed.

The three line endings at a glance

Name Code points Written in code as Bytes in ASCII or UTF-8 Main users
LF, line feed U+000A \n 0A Linux, macOS and other Unix-like systems
CRLF, carriage return + line feed U+000D U+000A \r\n 0D 0A Windows; email, HTTP and CSV
CR, carriage return U+000D \r 0D Classic Mac OS, up to version 9

With the hidden characters written out, the same two lines look like this in each convention:

LF      first line[LF]second line[LF]
CRLF    first line[CR][LF]second line[CR][LF]
CR      first line[CR]second line[CR]

Why a line ending can be two characters

The names come from teletypewriters. Carriage return moved the print head back to the left margin without advancing the paper. Line feed advanced the paper by one line without moving the print head. Starting a new line took both, and both codes were carried into ASCII and later into Unicode.

Operating systems then had to decide how to record the end of a line in a file, and they chose differently:

  • MS-DOS stored the pair, and Windows does the same.
  • Unix stored a line feed alone. Linux follows it, and so has the Mac since Mac OS X.
  • Classic Mac OS, through version 9, stored a carriage return alone.

None of the three is more correct than the others. The cost comes entirely from mixing them.

Where each convention still turns up

Windows software. Text saved by Windows programs usually has CRLF. Notepad has read LF-only and CR-only files since a 2018 update; before that it did not display an LF-only file correctly.

Email and HTTP. These are defined in terms of CRLF whatever system is at either end. The internet message format defines a line as ending in CRLF and says that CR and LF must only occur together. HTTP/1.1 ends its start line and every header line with CRLF.

CSV. RFC 4180, the common description of the format, ends each record with CRLF and says a field that itself contains a line break should be enclosed in double quotes. In practice LF-only CSV files turn up too, and many importers accept either. Line breaks inside cells are a separate hazard, covered in cleaning text for spreadsheets and databases.

Git. Git can convert line endings as files move between the repository and your working folder. A .gitattributes file sets the rule per path and travels with the repository, so every contributor gets the same result. Where no rule is set, Git falls back on the core.autocrlf configuration setting.

Editors. Code editors generally detect a file’s convention and keep it. VS Code, for example, preserves a file’s existing end-of-line sequence and has a Change End Of Line Sequence command for converting it.

Lone CR. Apart from files from old Macs, a bare carriage return appears in captured terminal output, where programs use it to redraw a progress line in place.

Line endings are only about which characters end a line. Whether a particular break is a line break or a paragraph break is a different question, answered in line break vs paragraph break.

Symptoms of a line-ending mismatch

What you see Likely cause
^M at the end of every line in a terminal tool or diff A CRLF file read by a tool that ends lines at LF and shows the leftover CR
A script that fails with a message such as bad interpreter: /bin/bash^M CRLF in a shell script, so the CR becomes part of the interpreter name
The whole file on one line An LF-only file in a program that only recognises CRLF, or a CR-only file in a program that only recognises LF
An empty line between every line CR and LF each treated as a line break, or a conversion applied twice
A diff in which every line changed although the text looks identical A tool rewrote every line ending when the file was saved
Values that look equal but do not match, often in the last column Lines split at LF while the data ends in CRLF, leaving an invisible CR on each value
Character counts or file sizes that differ by the number of lines CRLF counts as two characters and LF as one

^M is how many tools display a carriage return: it is the character that Control+M produces.

How to normalise line endings

Pick one convention for a file, or better for a whole project, and convert everything to it. LF is the common choice for code and for text shared across systems. Keep CRLF where a program or format specifically requires it.

Before (mixed endings)

Name,City[CR][LF]
Ana,Lisbon[LF]
Ben,Leeds[CR]Cara,Turin

After (normalised to LF)

Name,City[LF]
Ana,Lisbon[LF]
Ben,Leeds[LF]
Cara,Turin

In an editor

In VS Code, run the Change End Of Line Sequence command, choose LF or CRLF, and save. Other code editors have an equivalent command.

On the command line

  • dos2unix notes.txt converts CRLF to LF, and unix2dos notes.txt does the reverse.
  • tr -d '\r' < in.txt > out.txt deletes every CR, which turns CRLF into LF.
  • tr '\r' '\n' < in.txt > out.txt converts a CR-only file to LF. Use it only on a file that has CR alone. On a CRLF file it turns each ending into two line feeds, which is the empty-line symptom from the table.

With find and replace

In an editor whose regular-expression search matches line endings literally, find \r\n? and replace it with \n. The pattern matches a CR with or without an LF after it, so it handles CRLF and lone CR in one pass. When you write a pattern that has to match a line break in text of unknown origin, \r?\n covers both CRLF and LF.

In a Git repository

Put the rule in .gitattributes so it does not depend on each person’s settings:

* text=auto
*.sh text eol=lf
*.bat text eol=crlf

The first line lets Git detect text files and store them with LF. The other two fix the convention that particular file types get in the working folder. After adding the file, run git add --renormalize . and commit the result on its own, so the line-ending change is not mixed with real edits.

For pasted text

Both TextFixerr tools convert CRLF and CR to LF as their first step, before any other processing, and their output uses LF. Anything you run through the Text Cleaner or Remove Line Breaks therefore comes out with one consistent convention, and options that depend on line structure, such as joining wrapped lines while keeping paragraphs, behave the same whatever system the text came from.

This is a side effect of cleaning, not a converter. There is no option to produce CRLF or CR, and a downloaded .txt file has LF endings. If the destination needs CRLF, convert the file in an editor afterwards.

Frequently asked questions

Which should I choose, CRLF or LF?

LF, unless a program or format you depend on requires CRLF. Plain LF text is no longer a problem in Windows Notepad, and code editors handle both.

Does converting line endings change the text?

Not the words. It changes the bytes, so file sizes, checksums and exact comparisons differ, and a version-control system will report every line as modified once.

Sources

  1. CRLF - Glossary | MDN — MDN Web Docs
  2. The Unicode Standard 16.0, Chapter 5: Implementation Guidelines — Unicode Consortium
  3. Why is the line terminator CR+LF? — Microsoft (The Old New Thing)
  4. RFC 5322: Internet Message Format — IETF / RFC Editor
  5. RFC 9112: HTTP/1.1 — IETF / RFC Editor
  6. RFC 4180: Common Format and MIME Type for Comma-Separated Values (CSV) Files — IETF / RFC Editor
  7. Git - gitattributes Documentation — Git

This guide was drafted with AI assistance and reviewed by the publisher. See the editorial policy for how guides are written and corrected.