G-code is the language your 3D printer actually reads. When you hit “print,” the printer isn’t working from your 3D model directly. It’s following a long list of simple text commands, each one telling it exactly where to move, how fast to go, how much plastic to push out, and what temperature to hold. That list of commands is your G-code file.
From 3D Model to Printer Instructions
G-code originated in the 1950s as a standardized way to control CNC machines like mills and lathes. The name stands for “Geometric Code,” and the format was designed to break complex movements into simple, line-by-line instructions any machine could follow. When desktop 3D printing took off decades later, the community adopted the same language rather than inventing something new.
You never need to write G-code by hand. A piece of software called a slicer does that for you. You feed the slicer a 3D model (usually an STL or 3MF file), configure your settings (layer height, print speed, infill density, temperatures), and the slicer calculates the toolpath for every single layer. It figures out where the nozzle should travel, how much filament to extrude at each point, and how to build the object from bottom to top. The output is a .gcode file that can contain tens of thousands of lines for even a simple print.
Popular slicers like Cura, PrusaSlicer, and OrcaSlicer handle all of this automatically. But understanding what’s inside that file gives you the ability to troubleshoot problems, make small tweaks, and know what your printer is actually doing at any given moment.
What a Line of G-code Looks Like
Each line in a G-code file is a single instruction. It starts with a letter (called a “word”) followed by a number (called an “address”). Together, they tell the printer what action to take and with what parameters. Here’s a typical line:
G1 X25 Y40 Z0.3 E1.5 F1500
Breaking that down:
- G1 means “move in a straight line while extruding”
- X25 Y40 is the destination on the build plate, in millimeters
- Z0.3 is the height, so this is the first layer at 0.3 mm
- E1.5 tells the extruder to push out 1.5 mm of filament during the move
- F1500 sets the feed rate (speed) to 1500 mm per minute
Every line follows this same pattern. Some lines are movement commands, others control temperature or fan speed, and many include comments (marked with a semicolon) that the printer ignores but help humans read the file.
G-commands vs. M-commands
G-code files contain two main families of commands. G-commands handle movement and positioning. M-commands handle everything else: temperatures, fans, and machine-level functions. You’ll see both mixed throughout any print file.
Common G-commands
G0 is a rapid move. The printer travels as fast as possible without extruding filament. This is what you see when the nozzle zips between sections of a print without leaving a trail of plastic behind it.
G1 is a controlled linear move. This is the workhorse command, used for the vast majority of actual printing. Unlike G0, G1 lets you specify both speed and extrusion amount, so the printer lays down material at a precise rate.
G28 sends the printer back to its home position. This is typically the first command in any print file, making sure the machine knows exactly where it is before it starts building.
Common M-commands
Temperature commands are the M-codes you’ll encounter most often. M104 sets the nozzle to a target temperature and moves on immediately, while M109 sets the same temperature but pauses everything until the nozzle actually reaches it. The bed equivalents are M140 (set and continue) and M190 (set and wait). A typical start sequence heats both the bed and nozzle simultaneously using M140 and M104, then waits for each with M190 and M109 before printing begins.
Fan control uses M106 and M107. M106 turns the part cooling fan on, with an optional speed value from 0 to 255 (where S128 is roughly 50% power and S255 is full blast). M107 shuts the fan off. Your slicer adjusts fan speed throughout the print based on the layer, overhang angles, and bridging needs.
Absolute vs. Relative Positioning
Two commands control how the printer interprets coordinates, and the difference matters if you ever edit G-code manually.
G90 sets absolute positioning. Every coordinate refers to a fixed origin point on the build plate. If you tell the printer to move to X25 Y40, it goes to the same spot regardless of where the nozzle currently sits. This is the default mode for most of the print.
G91 switches to relative (incremental) positioning. Now X10 Y20 means “move 10 mm to the right and 20 mm forward from wherever you are right now.” The same command produces different results depending on the nozzle’s current location. This mode is commonly used in start and end scripts, for example when retracting filament or lifting the nozzle after a print finishes.
One quirk worth knowing: different printer firmwares handle these commands slightly differently. On some firmware, G91 sets the extruder to relative mode along with the X, Y, and Z axes. On others, the extruder requires a separate command (M83) to switch to relative extrusion. This is one of the reasons slicers ask you to select your specific printer or firmware before generating code.
Firmware Flavors and Compatibility
While G-code is technically standardized, the 3D printing world has developed several dialects. The three most common firmwares, Marlin, RepRapFirmware, and Klipper, all understand the core commands like G0, G1, and G28. But they diverge on less common features.
For example, firmware retraction (where the printer pulls filament back to prevent oozing) uses G10 and G11 on Marlin, the same codes on RepRapFirmware but with different parameter handling, and may not be supported at all on Klipper. Bed leveling commands vary too: Marlin uses G29 for its detailed probe routine, RepRapFirmware added G29 support in later versions, and Klipper maps the same function differently depending on configuration. Even something as basic as how feed rates are measured can differ. One firmware might expect millimeters per minute while another uses millimeters per second.
This is why slicers have a “G-code flavor” setting. When you select Marlin vs. Klipper vs. RepRapFirmware, the slicer adjusts the specific commands and syntax it outputs. Using the wrong flavor can cause anything from minor glitches to a failed print, so it’s worth confirming this matches your setup.
Previewing G-code Before Printing
Most slicers include a built-in G-code previewer that shows you a 3D visualization of the toolpath, layer by layer. This is the fastest way to catch problems before they waste filament: you can spot missing supports, poor layer adhesion areas, or unexpected travel moves just by scrubbing through the preview.
If you want to inspect G-code outside your slicer, browser-based tools like NC Viewer let you paste or upload a file and visualize the toolpath line by line, even simulating the print in real time. This is particularly useful when you’ve made manual edits and want to verify they look right before sending the file to your printer.
When You’d Actually Edit G-code
For most prints, you’ll never touch the G-code directly. The slicer handles everything. But there are situations where manual editing is useful.
Start and end scripts are the most common reason. These are short blocks of G-code that run before the first layer and after the last. You might customize your start script to include a specific nozzle wipe pattern, adjust the Z-offset, or add a purge line. End scripts typically retract filament, move the nozzle out of the way, turn off heaters, and disable the stepper motors so you can remove the print.
Mid-print changes are another use case. Some people insert filament color change commands at specific layers, pause commands for embedding magnets or nuts, or temperature adjustments for different sections of a print. You can do this by opening the .gcode file in any text editor, finding the layer where you want the change, and inserting the appropriate command. A filament change, for instance, is typically a single M600 command on one line.
Because G-code is plain text, it’s approachable even if you’re not a programmer. You can open any .gcode file, scroll through it, and start recognizing the patterns within minutes. The commands repeat constantly, and once you know what G0, G1, and a handful of M-codes do, you can read the majority of any print file.

