Open a file and see ^M at the end of every line. Or run a shell script and hit a bad interpreter error. You have just met the difference between CRLF vs LF line endings. Two invisible characters decide where one line ends and the next begins. Windows, Linux, and macOS have never agreed on which bytes to use. Here is what the three conventions mean, why that ^M appears, and how to switch between formats without breaking your files.
What Are Line Endings?
In plain text, a line ending is a sequence of bytes that tells a program, editor, or terminal where a line ends. Without those bytes, all your text runs together as one long string. Different operating systems chose different bytes. That is why the same file looks perfect on one system and broken on another.
Three conventions exist:
- LF (line feed, byte 0x0A, written \n). Linux and macOS have used this since Mac OS X.
- CRLF (carriage return + line feed, bytes 0x0D 0x0A, written \r\n). Windows uses this.
- CR (carriage return, byte 0x0D, written \r). Classic Mac OS used this up to version 9.
Press Enter in an editor and it inserts the line ending the editor believes your operating system expects. Trouble starts when you move that file to a different system, or open it in a tool that expects a different ending.
CRLF vs LF the Windows and Unix Difference
Why the Two Clash
The most common clash is between Windows and Unix-like systems. Windows uses CRLF (\r\n). Linux and modern macOS use LF (\n). Open a Windows-created file on Linux and the extra carriage return (\r) sits there invisibly in most text editors. Open a Unix-created file on older Windows Notepad and you see one long line. Notepad did not recognize LF as a line break.
This difference causes several practical problems:
- Shell scripts written on Windows fail on Linux with an error like /bin/bash^M: bad interpreter. The shell sees the ^M as part of the interpreter path.
- Configuration files, Python scripts, and any file that expects exact characters break when an extra \r is present.
- Version control systems flag every line as changed if line endings are inconsistent.
Tools That Handle the Gap
Modern tools cope better. Windows Notepad has supported LF and CR line endings since the Windows 10 October 2018 Update (version 1809). Before that, LF files appeared as one long line. VS Code shows CRLF or LF in its status bar. Click it to switch. But the underlying bytes still matter. They matter most when you share files between systems.
The ^M Problem Why You See it
The ^M you see in some Unix tools is caret notation for the carriage return character (byte 0x0D). When a file uses CRLF line endings and you view it with a tool that only recognizes LF as a line break, the \r displays as ^M at the end of each line. It is not a formatting mistake in your text. The tool is showing you the hidden byte.
This happens most when you copy a file from Windows to Linux or macOS. The file still contains \r\n at the end of each line. The Unix tool splits lines only on \n. The \r becomes part of the line content, and you see ^M.
The same problem hits shell scripts. Write a script on Windows and run it on Linux. The interpreter path line (the shebang line) ends with \r\n. The kernel sees /bin/bash^M as the interpreter. You get /bin/bash^M: bad interpreter. Fix the line endings. Do not edit the script manually.
How to Convert CRLF to LF (and Back)
Command-Line Tools
Switching between line endings is straightforward. Use the dos2unix and unix2dos utilities, available on most Linux and macOS systems. They handle CRLF, LF, and CR.
- To switch a file from Windows to Unix format, run: dos2unix filename
- To switch from Unix to Windows, run: unix2dos filename
- Specify an output file: dos2unix input.txt output.txt
Editors and Git
No command-line utilities? Use a text editor. In VS Code, click the CRLF or LF button in the status bar to switch the current file's line ending. Most editors also let you change the default line ending in settings.
For Git users, the core.autocrlf setting handles line endings automatically on checkout and commit. This helps when you collaborate across systems. Choose a consistent policy, or expect unexpected changes.
Line Endings in Browsers and Forms
Line endings appear in web forms too. Submit a form with a textarea and the browser sends the text with CRLF line endings. This happens even if the textarea content uses LF internally. The HTML specification mandates this. Your server-side code must be ready to handle CRLF.
In practice, most server-side languages normalize line endings when processing form data. Rarely does this cause trouble. But if you build a tool that processes raw form input, know that the line breaks you receive may be CRLF, not LF.
Inside the browser's DOM, a textarea's value uses LF line breaks. This holds true even when the user pastes text with CRLF. The browser normalizes to LF for the DOM value, then switches back to CRLF only when submitting the form. The detail is subtle. It matters for JavaScript code that reads or manipulates textarea content.
Choosing a Line Ending for Your Project
No single line ending fits every situation. Consistency does. Work on a project developed primarily on Linux or macOS? Use LF. Stuck with Windows-only tools or legacy files? CRLF may be unavoidable. Know what your tools expect. Switch when necessary.
For text files shared across systems, many developers prefer LF. It is simpler and less likely to cause issues in Unix-based tools. Some Windows-native tools still expect CRLF. You may need to switch files when you check them out or commit them.
Using Git? Configure core.autocrlf to handle the conversion. On Windows, set it to true so files check out with CRLF and commit with LF. On Linux or macOS, set it to input. This switches CRLF to LF on commit but not on checkout.
Practical Tips to Avoid Line Ending Problems
Daily Habits
- Set your editor to use LF for new files unless you specifically need CRLF.
- Check the status bar in VS Code. It shows which line ending the current file uses.
- Use dos2unix or unix2dos in your build scripts to normalize files before deployment.
- Save shell scripts with LF, even on Windows. Use an editor that supports Unix line endings.
- See ^M in a file? Do not delete each one by hand. Convert the file with a tool.
Why It Matters
Line endings are invisible. They are still part of the file's content. A single stray \r can crash a script or misread a configuration file. Knowing the difference between CRLF and LF, and knowing how to switch between them, is a basic skill for anyone who works with plain text.