ANSI escape codes are control-byte sequences that begin with the ESC character (decimal 27, hexadecimal 0x1B), followed by a left bracket, one or more semicolon-separated Select Graphic Rendition (SGR) parameters, and the letter m, used to change foreground color, background color, and text styling for the characters that follow. A typical full sequence reads as ESC[<params>m<text>ESC[0m, where the trailing reset clears any active formatting once the colored text has been printed. The ESC byte itself is invisible; what makes an escape code recognizable to a terminal is the bracketed parameter block, not printable characters on the page. ECMA-48 standardizes the format and the base rendition controls, and xterm documentation cross-checks the bright mappings that most Linux and macOS terminal emulators have adopted. When you write a script or a debugging fixture, you can construct these bytes by hand, but a tool such as the ANSI Color Codes Generator lets you enter text, choose optional foreground, background, bold, and underline settings, and copy the exact raw control-byte string that a terminal-aware consumer expects.

The format of an ANSI escape code
The Control Sequence Introducer (CSI) is the most common shape of ANSI escape code in modern terminals. It is ESC followed by a left bracket, zero or more numeric parameters separated by semicolons, and a final byte that names the operation. The letter m names the SGR operation; other letters such as H, J, K, or A perform cursor moves, screen clears, or line erases, but those are outside the scope of color and style.
The minimal SGR form is ESC[0m, which resets every active graphic rendition. Setting only a foreground color uses one parameter, for example ESC[31m for the second base foreground slot (red). Combining multiple properties stacks the parameters: ESC[1;4;91;44m turns bold on, underline on, sets bright red foreground (91), and sets blue background (44). The terminal applies every listed property at once and remembers them until a new prefix or a reset arrives.
Two practical notes follow from this structure. First, parameters are decimal integers; hex, octal, or symbolic forms are not parsed by the terminal. Second, the m terminator is mandatory; without it the terminal keeps reading bytes as parameters, which produces either an ignored sequence or an unintended action downstream. The ANSI Color Codes Generator always emits a complete prefix and an appended ESC[0m reset, so the bracketed parameter block is balanced and the active rendition ends at the right place in the byte stream.
How SGR parameters are organized
SGR parameters follow a fixed numeric map. Style parameters toggle attributes, color parameters select palette slots. ECMA-48 defines the base rendition controls; the xterm control sequences documentation cross-checks the bright mappings that most modern emulators implement on top of that base.
| Code | Meaning |
|---|---|
| 0 | Reset all attributes |
| 1 | Bold (or increased intensity on some terminals) |
| 4 | Underline |
| 30-37 | Base foreground palette: black, red, green, yellow, blue, magenta, cyan, white |
| 40-47 | Base background palette in the same eight colors |
| 90-97 | Bright foreground palette (xterm-compatible extension) |
| 100-107 | Bright background palette (xterm-compatible extension) |
The base 30-37 range and its 40-47 background mirror are the eight palette slots every conforming terminal must accept. The 90-97 and 100-107 ranges are an extension that most Linux and macOS emulators support but ECMA-48 does not mandate. Unsupported style or color numbers are rejected by the generator so the produced sequence stays portable across consumers.
One detail worth remembering: a color number selects a palette slot, not an exact RGB value. The actual on-screen color depends on the terminal theme, user accessibility settings, multiplexers, and remote environments that may remap those slots between your script and the user. The generator deliberately does not display a fake in-browser color preview because that would imply a single universal terminal palette exists where there is none.
Why a generator helps with ANSI escape codes
Hand-writing SGR sequences is straightforward once the parameter map is memorized, but mistakes are easy to ship. A missing bracket, a literal backslash sequence instead of the ESC byte, or a forgotten reset leaves the next stream of output formatted in a way you did not intend, and the bug often surfaces only in a downstream terminal you did not test locally. The visible output of the ANSI Color Codes Generator writes the escape byte as \x1b so the sequence can be reviewed in the browser without changing the appearance of the page itself; the underlying control bytes are still produced exactly as a terminal expects.
Three practical benefits follow. You can search a 16-color reference table instead of memorizing which integer maps to which color slot. You can apply the smallest necessary set of parameters rather than emitting every attribute, which keeps log fixtures short and readable. And you can copy the raw escape sequence only, knowing that the generator has validated the parameters and appended a reset. Raw escape bytes are control data, and pasting them into the wrong place, such as a chat message, an inline comment, or an issue tracker, produces invisible behavior rather than readable text. The Copy raw sequence button places the actual ESC control byte plus the parameters plus the text plus a reset on the clipboard, not the four visible characters backslash-x-1-b.
For ad-hoc debugging, scripting, or fixture authoring, this removes a class of off-by-one errors that frequently appear in handwritten ANSI helpers. For larger projects, the same pattern serves as a useful baseline; any time your library starts hand-assembling the ESC byte, you can verify the result against what the generator emits and compare the raw bytes character by character.
How to build an SGR sequence with the ANSI Color Codes Generator
- Open the ANSI Color Codes Generator in your browser and enter the terminal text you want to format in the input field.
- Pick an optional foreground from the base or bright palette, an optional background, and toggle bold or underline if needed. Leave any setting unset if you do not want that attribute.
- Generate the sequence. The visible escaped representation writes the escape byte as \x1b so you can read it, and the SGR parameters panel shows the exact decimal numbers being emitted.
- Copy the raw sequence with the Copy button. The clipboard now holds the actual ESC byte plus bracketed parameters plus your text plus the closing ESC[0m reset.
- Paste only into a trusted, terminal-aware context: a source string in a script, a fixture file, a REPL, a debugger, or a CI log that is being inspected by a terminal-aware consumer.
- Test the reset behavior by printing something after the formatted text. The next visible character should appear with default styling, which confirms the trailing ESC[0m reset cleared the active rendition.
A worked example: choosing bright red foreground, blue background, bold, and underline produces the parameter string 1;4;91;44. The generator emits ESC[1;4;91;44m<your text>ESC[0m, which a typical xterm-compatible emulator renders as bold underlined bright-red text on a blue background, then returns to default styling immediately after the reset byte.
Escape codes in logs and untrusted text
Raw escape sequences are control data, not printable characters. Pasting them into a terminal command line, a chat transcript, a log file, or a source comment can produce invisible behavior rather than readable text. Because the ESC byte has no glyph, the formatted output looks like ordinary characters on a web page or a basic text viewer, yet it executes side effects inside an interactive terminal: cursor moves, color changes, screen clears, or text reflow that hides part of a line.
Logs containing untrusted control bytes are a documented risk. Attackers can hide text, forge visual lines that point at misleading links, create fake status indicators, or disrupt terminal state for the next user who opens the file. Treat any control bytes in untrusted text as potentially hostile. Sanitize the data before printing it to an interactive terminal, and provide a plain-text logging path where control sequences are removed or visibly escaped, for example by writing \x1b instead of the byte itself.
The generator helps by writing the visible representation as \x1b, but the moment you click Copy raw sequence you have real control bytes on your clipboard. Before pasting, ask whether the destination will be opened by a terminal-aware consumer that interprets SGR, a plain text editor that shows the bytes literally, or a downstream log pipeline that strips control characters. The same sequence is safe in a script source string, helpful in a debugging fixture, and dangerous in an issue comment where it can be replayed by a reader's terminal emulator.
Testing sequences before you ship
Even a perfectly formed SGR sequence is only as good as the consumer that reads it. Modern emulators on Linux and macOS implement the base 30-37 and 40-47 codes and the xterm bright extensions; older terminals, multiplexers like tmux or screen, redirected non-interactive output, and remote shells can each alter the visible result. ECMA-48 defines the standard, but it does not mandate the bright palette; xterm-compatible mappings are the de facto choice. Some applications honor the NO_COLOR convention and skip SGR entirely; some detect Windows virtual terminal processing and emit different codes; some disable color whenever stdout is not a terminal.
Two practical checks help. First, generate the smallest set of parameters you actually need, such as a single foreground color rather than bold plus underline plus a bright variant unless each attribute is genuinely required, and verify the visible representation reads the way you expect. Second, paste the raw sequence into the real terminal, theme, and output mode your users will run, then print a normal character immediately after to confirm the trailing reset cleared the active rendition. A reset is a guardrail, not a guarantee that every consumer interprets the stream identically.
If your output may be displayed by an application that cannot interpret SGR, provide a way to disable color. The page itself has no terminal emulator and cannot determine whether a destination supports ECMA-48, xterm extensions, Windows virtual terminal processing, NO_COLOR conventions, or redirected non-interactive output, so the final verification must happen against the real destination rather than against the generator.