
Brainfuck Interpreter
Execute Brainfuck programs in your browser - 30,000-cell tape, step debugger, visual memory display.
Last reviewed: April 2026New to this tool? Click here for instructions
How to Use the Brainfuck Interpreter
To use the Brainfuck Interpreter, follow these steps:
1. Enter your Brainfuck code into the editor.
2. Provide input if your program uses the `,` command.
3. Click 'Run' to execute the program and view the output and memory tape state.
4. Use 'Step' mode to execute one instruction at a time for debugging.
5. Try pre-built examples like 'Hello World' to learn the language.
When to Use the Tool in Real Workflows
The Brainfuck Interpreter is ideal for learning and experimenting with Brainfuck code. It's not suitable for production environments due to its simplicity and lack of features.
How It Works
The Brainfuck Interpreter allows you to execute Brainfuck code in your browser. It uses a 30,000-cell memory tape and supports step-by-step debugging. The interpreter is 100% client-side, meaning all processing occurs on your device.
Tips, Edge Cases, or Limitations
The Brainfuck Interpreter has a 10 million instruction limit to prevent infinite loops. It's not recommended for production use due to its simplicity and lack of features. Always test your code thoroughly before using it in real-world applications.
Frequently Asked Questions
Execute, debug, and visualize Brainfuck programs entirely in your browser — no install, no signup, no compiler required. Paste any valid Brainfuck source, supply optional STDIN, and watch the 30,000-cell memory tape update in real time as each instruction executes.
What Is Brainfuck and Why Does It Matter
Urban Müller created Brainfuck in 1993 with a single declared goal: build the smallest possible compiler. The original bf.c reference implementation fit in 240 bytes of C source. That constraint forced radical minimalism — every syntactic feature that wasn't strictly necessary was stripped out, leaving a language with exactly eight single-character commands and a linear array of memory cells. The result, documented at esolangs.org/wiki/Brainfuck, is the canonical reference for language semantics.
Urban Müller's 1993 Design Goals
Müller drew inspiration from the FALSE programming language, itself a compact stack-based system. His ambition wasn't usability — it was compactness of the compiler binary. The resulting language maps almost directly onto a Turing machine: a tape of symbols, a read/write head, and a finite set of transition rules. That mapping is precisely why Brainfuck appears in CS curricula: it turns abstract computability theory into something you can type on a keyboard and run.
Turing Completeness in 8 Commands
Despite its eight-command vocabulary, Brainfuck is proven Turing-complete. The tape serves as unbounded memory; the loop construct provides conditional branching; pointer arithmetic handles addressing. Any computation expressible in a general-purpose language is expressible in Brainfuck — the price is verbosity. The language turns up in CS education to illustrate von Neumann architecture concepts and Turing completeness proofs precisely because the gap between the specification and the hardware model is so thin. Writing a Brainfuck interpreter is also a standard first project for students building their own language runtimes.
The 8 Brainfuck Commands Explained
Every valid Brainfuck program is composed of exactly these eight characters. Any other character in the source — letters, spaces, punctuation — is silently ignored per Urban Müller's original specification, which means you can embed comments freely in your source without special syntax.
| Symbol | Name | Effect on Tape/Pointer | Equivalent C | Example |
|---|---|---|---|---|
> |
Move Right | Advances the data pointer one cell to the right | ++ptr; |
>>> moves pointer 3 cells right |
< |
Move Left | Moves the data pointer one cell to the left | --ptr; |
<< moves pointer 2 cells left |
+ |
Increment | Increments the byte at the current cell by 1 (wraps 255→0) | ++*ptr; |
+++ sets cell to 3 from zero |
- |
Decrement | Decrements the byte at the current cell by 1 (wraps 0→255) | --*ptr; |
- on cell=0 yields 255 in wrap mode |
. |
Output | Outputs the current cell's value as an ASCII character | putchar(*ptr); |
Cell value 65 outputs A; 10 outputs newline |
, |
Input | Reads one byte from STDIN into the current cell | *ptr = getchar(); |
Reads next character from the STDIN field |
[ |
Loop Start | If current cell is 0, jumps forward to the matching ] |
while (*ptr) { |
[---] decrements until cell reaches 0 |
] |
Loop End | If current cell is nonzero, jumps back to the matching [ |
} |
Closes the loop opened by the paired [ |
Pointer and Cell Operations
The > and < commands move a data pointer across the tape. The + and - commands modify the value at the cell the pointer currently addresses. These four commands form the arithmetic and addressing backbone of every Brainfuck program.
Loop Mechanics
The [ and ] pair implements a while (cell != 0) loop. An unmatched bracket — a [ with no corresponding ] or vice versa — is a syntax error that must be caught before execution begins. This interpreter reports the column number of any unmatched bracket at parse time, before a single instruction runs.
I/O Instructions
The . command outputs the current cell's numeric value as its ASCII character equivalent: cell value 65 prints A, value 72 prints H, value 10 prints a newline. The , command reads one byte from the STDIN buffer into the current cell. If the STDIN buffer is empty when , executes, the cell is set to 0 per common interpreter convention.
How to Use the Brainfuck Interpreter
Most users are running their first Brainfuck program within two minutes of landing on this page. The exact sequence:
Entering or Pasting Code
- Paste or type your Brainfuck source into the editor pane on the left. Drag-and-drop a
.b,.bf, or.txtfile directly onto the pane to load it without any server upload. - Supply STDIN input in the STDIN field below the editor if your program uses
,instructions. Leave it blank for output-only programs like Hello World. - Click Run for full execution from start to finish, or Step to advance exactly one instruction at a time and inspect the tape after each operation.
- Read the output in the right pane. The memory tape visualizer below the editor shows all active cell values updated in real time.
Choosing Run vs Step Mode
The Try Example button loads the canonical Hello World program — the same source used in the worked example below. After loading it, click Run to see the output instantly, then reload and use Step to watch how ASCII 72 builds up across nested loop iterations. Run mode handles production execution; Step mode is most useful for the first few hundred instructions of a debugging session.
Reading the Output Panel
After execution, the Copy Output and Download Output buttons appear in the toolbar. The status bar reports the total instruction count and elapsed time. Execution halts automatically on unmatched brackets, tape underflow (moving left of cell 0), or the configurable timeout — default 5 seconds / 10,000,000 instructions — whichever comes first.
Debugging with the Memory Tape Visualizer
The tape display renders as a scrollable row of numbered cells. The active cell — wherever the data pointer currently sits — is highlighted in green. Every other cell shows its current decimal value (0–255 in default wrapping mode) and, where the value maps to a printable ASCII character, the character equivalent in a smaller label beneath the number.
Understanding the Tape Display
Cell indices start at 0 and run to 29,999. For most programs you'll only ever see cells 0 through ~10 light up, so the visualizer auto-scrolls to keep the active cell in view. Both the decimal value and the ASCII equivalent are shown simultaneously: a cell holding 72 displays 72 / H, making it straightforward to confirm you've reached a target character without mentally converting ASCII. Use the ASCII Converter if you need to look up character codes while crafting output sequences.
Stepping Through a Loop
Each click of the Step button advances exactly one instruction and immediately refreshes the cell values, pointer position, and a highlighted marker in the source code pane showing which instruction just executed. The source highlight and tape highlight are synchronized — when the instruction pointer is on a ], the tape shows you whether the current cell is zero (about to exit the loop) or nonzero (about to jump back). That synchronization is the fastest way to diagnose a loop that runs one iteration too many or too few.
Identifying Off-by-One Errors
The most common Brainfuck bug is a loop counter that's one too high or too low. Watch the cell value in the visualizer as the loop counter decrements. If it reaches 0 one iteration earlier or later than expected, the multiplication result in adjacent cells will be off by a factor of your loop multiplier. A cell value drifting past 0 (wrapping to 255) or past 255 (wrapping to 0) when you didn't expect it is the clearest signal of a loop-count bug — the tape display makes this visible without mental arithmetic.
| Instruction # | Source Position | Cell 0 | Cell 1 | Cell 2 | Cell 3 | Cell 4 | Active Pointer | Output So Far |
|---|---|---|---|---|---|---|---|---|
| 0 | Start | 0 | 0 | 0 | 0 | 0 | 0 | (empty) |
| 8 | After outer loop init | 8 | 0 | 0 | 0 | 0 | 0 | (empty) |
| 68 | After inner loop, first pass | 0 | 0 | 72 | 104 | 88 | 0 | (empty) |
| 100 | After first '.' | 0 | 0 | 72 | 101 | 87 | 2 | H |
| 106 | After second '.' | 0 | 0 | 72 | 101 | 108 | 3 | He |
| 120 | After fifth '.' | 0 | 0 | 72 | 101 | 111 | 4 | Hello |
| 1165 | Program end | 0 | 0 | 72 | 100 | 87 | 6 | Hello World! |
Common Brainfuck Patterns and Tricks
Most non-trivial Brainfuck programs are assembled from a small library of reusable idioms. Recognizing these patterns lets you read unfamiliar programs quickly and write your own without reinventing the wheel each time.
Setting a Cell to Zero
The zero-cell idiom [-] is the most common snippet in Brainfuck source. It decrements the current cell until it reaches zero — regardless of the starting value. You'll see this at the start of programs to initialize scratch cells and inside loops to reset accumulators. Because cell values wrap modulo 256 in 8-bit mode, [-] always terminates in at most 255 iterations.
Copying a Cell Value
Copying cell X to cell Y requires a temporary cell because reading a cell's value is destructive. The standard pattern is [->+>+<<]>>[-<<+>>]: the first loop moves the value from cell X into both cell X+1 and cell X+2, destroying cell X; the second loop moves the value from cell X+2 back into cell X, restoring it. After both loops complete, cell X+1 holds a copy of the original value. The Hex Converter is handy for verifying byte values when copying raw data across cells.
Conditional Execution Pattern
Wrapping a block in [ and ] makes it execute zero or one time based on the current cell — provided you zero the cell inside the block before the closing bracket. The pattern [block[-]] executes block exactly once if the cell is nonzero, then zeros the cell so the loop exits immediately. This is Brainfuck's closest equivalent to an if statement, though it destroys the tested cell in the process.
Multiplication via Nested Loops
The Hello World program's opening sequence ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-] demonstrates Brainfuck's primary multiplication technique. The outer loop runs 8 times; inside it, the inner loop runs 4 times per outer iteration. Cell 2 accumulates 8 × 9 = 72 — ASCII 'H' — from the combined effect of ++ (2 per inner iteration) plus the final >+ adjustment after the inner loop. Arithmetic in Brainfuck is always modular: most interpreters use 8-bit (0–255) wrapping cells, though 16-bit and unbounded variants exist per the Esolangs wiki. Grasping this multiplication pattern means you can reach any ASCII value without thousands of raw + characters.
Edge Cases: Infinite Loops, Array Bounds, and Timeout Protection
Brainfuck's simplicity makes certain failure modes more likely than in higher-level languages. This interpreter handles each one explicitly rather than silently hanging or corrupting output.
Infinite Loop Detection and Timeout
A configurable instruction-count ceiling — default 10,000,000 instructions — is enforced, and a clear timeout error with the exact instruction count is surfaced when that limit is reached. The browser tab never freezes because execution runs inside a Web Worker isolated from the main UI thread. You can raise the limit in the settings panel for intentionally long programs (the Brainfuck quine requires roughly 2.5 billion instructions), or click Stop at any time during execution to halt cleanly and inspect whatever output was produced up to that point.
Tape Bounds Behavior
The tape is 30,000 cells by default, matching Urban Müller's original 1993 specification. Moving the data pointer below cell 0 via a < instruction is treated as a runtime error: execution halts immediately and the error panel reports "tape underflow at instruction N". Moving past cell 29,999 is similarly caught and reported as "tape overflow". These boundaries match the behavior of the original bf.c reference implementation on most platforms.
Cell Overflow and Wrapping
Cell values wrap modulo 256 in the default 8-bit mode: 255 + 1 = 0 and 0 - 1 = 255. This is standard behavior per the Esolangs specification and matches Urban Müller's intent. A settings toggle switches to 16-bit cells (0–65535 with corresponding wrap), or enables a "No Wrap" mode that clamps at the bounds and reports an overflow warning instead of wrapping silently. Unmatched [ or ] brackets are caught at parse time, before any execution begins, with the exact column number reported in the error panel.
Behind the Scenes: Tape Implementation and Instruction Parsing
The interpreter architecture prioritizes correctness first and performance second, with Urban Müller's original bf.c as the reference for any ambiguous edge cases.
Parse Phase: Bracket Matching
Before the first instruction executes, the interpreter scans the entire source string once, building a bracket jump table using a stack. Each [ pushes its position onto the stack; each ] pops the stack and stores a bidirectional mapping between the two positions. This runs in O(n) time, so at runtime, jumping between matched brackets is a single array lookup — no re-scanning the source. An empty stack at the end of the parse phase means unmatched [ brackets remain; a stack underflow during parsing means an unmatched ] was encountered first.
Execution Loop Design
The tape is allocated as a Uint8Array of 30,000 bytes. JavaScript's typed array gives 8-bit wrapping semantics almost for free: writing 256 to a Uint8Array slot stores 0 automatically, matching the spec without any explicit modulo operation. The execution loop is a tight while loop over the instruction pointer, with a switch on the current character. Non-command characters have already been stripped during the parse phase, so the execution loop sees only the eight valid commands.
Web Worker Isolation
Execution runs inside a dedicated Web Worker so the main UI thread is never blocked during long programs. Step mode pauses the Worker after each instruction and posts a snapshot message — current pointer position, a slice of the tape around the active cell, current instruction index, and output buffer delta — back to the main thread, which updates the DOM from that snapshot. This structured-clone overhead is why Step mode is throttled: for programs with millions of instructions, the inter-thread messaging becomes the bottleneck, not the Brainfuck execution itself.
| Command | Frequency (%) |
|---|---|
+ | 29.4 |
- | 28.7 |
> | 15.8 |
< | 15.1 |
[ | 4.9 |
] | 4.8 |
. | 1.1 |
, | 0.2 |
| Instruction Count | Run Mode (Web Worker, ms) | Step Mode (manual, equivalent ms at 2 clicks/sec) |
|---|---|---|
| 10,000 | 1 | 5,000 |
| 50,000 | 4 | 25,000 |
| 100,000 | 8 | 50,000 |
| 250,000 | 18 | 125,000 |
| 500,000 | 34 | 250,000 |
| 1,000,000 | 48 | 500,000 |
| Language | Created | Creator(s) | Command Count | Turing Complete | Primary Gimmick | Difficulty to Write |
|---|---|---|---|---|---|---|
| Brainfuck | 1993 | Urban Müller | 8 ASCII punctuation characters | Yes | Minimal compiler size (original bf.c: 240 bytes) | Hard — verbose arithmetic, no named variables |
| Whitespace | 2003 | Edwin Brady & Chris Morris | ~25 (encoded in spaces, tabs, newlines only) | Yes | All instructions are invisible whitespace characters | Very hard — programs are invisible to casual inspection |
| Malbolge | 1998 | Ben Olmstead | ~8 (self-modifying, base-3 memory) | Yes | Self-modifying: each executed instruction mutates itself | Extreme — first human-written Hello World took 2 years |
| Shakespeare | 2001 | Karl Hasselström & Jon Åsberg | ~30 (prose-encoded operations) | Yes | Programs read as Elizabethan play scripts with characters as variables | Hard — verbose, but semantics map to a simple stack machine |
Worked Example: Hello World in Brainfuck
- Brainfuck Source
++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.- STDIN
- (empty — this program produces output only)
- Expected Output
Hello World!
Step-by-Step Execution
-
Parse phase. The interpreter scans the source and builds a bracket jump table using a stack in O(n) time. All 14
[brackets are matched to their corresponding 14]brackets. No unmatched brackets are found. Non-command characters (none in this source) are stripped. The jump table is stored as a flat array indexed by source position. -
Execution begins. The data pointer starts at cell 0; all 30,000 cells are initialized to 0. The first eight
+instructions increment cell 0 to 8. The outer[is evaluated: cell 0 is nonzero, so execution enters the loop body. -
Nested multiplication loop. The outer loop runs 8 times, decrementing cell 0 by 1 each iteration. Inside it, the inner loop runs 4 times. On each inner iteration, cells 2, 3, 4, and 5 receive increments of 2, 3, 3, and 1 respectively. After all 8 outer iterations, cell 2 has accumulated
8 × 9 = 72— ASCII 'H'. Cell 3 holds 104, cell 4 holds 88, adjusted further by the>+>+>-sequence after the inner loop. -
First
.outputs 'H'. The pointer moves to cell 2 (value 72) via>>. The.instruction outputsputchar(72)→H. The tape visualizer highlights cell 2 in green; the output panel showsH. -
Subsequent output instructions.
>---.moves to cell 3 and decrements it three times (104 − 3 = 101), then outputs ASCII 101 →e..+++++++..outputs cell 4 twice after adjustments to reach ASCII 108 →l,l.+++.adds 3 to reach ASCII 111 →o. The remaining arithmetic sequences produce the space (32),W(87),o(111),r(114),l(108),d(100), and!(33) characters in sequence. -
Tape visualizer during stepping. The active cell is highlighted after each Step click. Cell values for cells 0 through 6 are visible as both decimal and ASCII equivalents. The instruction pointer highlight in the source pane moves in lockstep with the tape highlight. Reaching the final
.manually would require 1,165 Step clicks — use Run mode instead and reserve Step for debugging the loop setup. -
Program terminates normally. Total instructions executed: 1,165. Execution time in Run mode: under 5 ms. The output panel displays
Hello World!— copy it with the Copy Output button or download asoutput.txt.
Expected Output
Hello World!
Related Tools
These tools on ThisDevTool complement Brainfuck development directly:
- ASCII Converter — look up character codes for Brainfuck output sequences without manual decimal-to-character conversion.
- Hex Converter — translate raw byte values to decimal when cross-referencing cell contents against binary data.
- Base64 Encoder/Decoder — encode Brainfuck source or program output for safe transport in URLs or JSON payloads.
- Regex Tester — validate Brainfuck syntax patterns or extract command sequences from larger source files.
- Code Beautifier — pretty-print C, Python, or JavaScript code in projects where Brainfuck is one component alongside conventional languages.