G-Code & M-Code Fundamentals

Every CNC machine—mill, lathe, router, or machining center—runs on the same basic language: lines of G-codes and M-codes that tell it where to move, how fast, and when to turn things on and off. This page is the on-ramp. If you can read a tape measure and you have watched a machine cut, this is everything you need to start reading a program and understanding what each line does. No prior code experience assumed.

What a G-Code Program Actually Is

A CNC program is a plain-text list of instructions the control reads top to bottom, one line at a time. The vocabulary is small and rigid, which is good news—there is a fixed set of building blocks and once you know them, every program looks familiar.

The two families of codes that do the heavy lifting have formal names worth knowing:

  • G-codes are the preparatory commands. They prepare (preset) the control into a mode of operation—rapid vs. feed motion, inch vs. metric, absolute vs. incremental. Think of them as the machine's settings and moves.
  • M-codes are the miscellaneous functions. They switch hardware and manage program flow—spindle on/off, coolant on/off, tool change, program end.

Everything else in a program is built from a handful of pieces:

Piece What it is Example
WordA single instruction: one letter (the address) followed by a numberG01, X2.5, F10.
BlockOne line of the program—one or more words the control executes togetherG01 X2.5 Y1.0 F10.
Sequence numberAn optional N word that labels a block so you can find or search to itN50
Program numberThe O word that names the program in control memory (Fanuc)O0001
CommentHuman notes in parentheses—ignored by the machine(DRILL 1/4 HOLE)
Block skipA leading / makes the control skip that block only when the Block Skip switch is on/M08
Program markerThe % character marks the start and end of the program file%

A word is always a letter plus a number. The letter (the address) says what kind of information follows; the number is the value. X2.5 means "X axis, 2.5 units." F10. means "feedrate, 10." Here are the address letters a beginner meets first:

Address Meaning
OProgram number
NBlock (sequence) number
GPreparatory command (a mode or a move)
MMiscellaneous function (hardware / flow)
X Y ZAxis positions
FFeedrate (cutting speed of the tool through the material)
SSpindle speed (RPM)
TTool number
H / DOffset register numbers (length / diameter)
RRadius or a retract/reference height in a cycle
P / LDwell time, subprogram number, or repeat count (context-dependent)

Anatomy of a Block

Read this single block left to right and you have read a CNC program in miniature:

N50 G01 X2.5 Y1.0 Z-0.25 F10. (CUT TO CORNER)
|   |    |    |     |     |    |
|   |    |    |     |     |    +-- comment, ignored by the machine
|   |    |    |     |     +------- F10.  feedrate: 10 units per minute
|   |    |    |     +------------- Z-0.25 depth
|   |    |    +------------------- Y1.0  Y position
|   |    +------------------------ X2.5  X position
|   +----------------------------- G01   move in a straight line at feed
+--------------------------------- N50   this block's sequence number

Order of words inside a block does not usually matter to the control, but shops write them in a consistent order (G, then coordinates, then F) so programs are easy to read. What does matter is which codes are present—and, as the next section explains, which codes are still active from earlier blocks.

The Big Idea: Modal vs Non-Modal

This is the single most important concept for a beginner, and the one that causes the most crashes when it is misunderstood.

A modal code stays in effect once you program it—it stays active block after block until you change it. A non-modal (or "one-shot") code takes effect for its own block only, then evaporates. Most G-codes are modal; most M-codes are one-shots.

Because motion codes are modal, you do not repeat them on every line. Look:

G01 X1.0 Y1.0 F10.   (G01 selects straight-line feed)
X2.0                 (STILL G01 - no need to repeat it)
X3.0 Y2.0            (STILL G01, STILL F10.)
G00 X0 Y0            (now G00 rapid REPLACES G01)

The flip side is the trap: a mode you set 30 lines ago is still on unless something canceled it. Leave the control in G91 incremental when the next block assumes absolute, and the tool goes somewhere you did not intend. This "leftover mode" problem is exactly why programs open with a safe start line (shown later) that forces the important modes to known values before any cutting begins.

Modal Groups: One Winner Per Category

Modal codes are organized into modal groups. A group is a set of codes that do the same kind of job—and only one code from a group can be active at a time. Program a new code from a group and it automatically replaces whatever was active in that group. You cannot be in rapid G00 and feed G01 at once; they are in the same group, so the later one wins.

One code from each group is active at all times active now Group 01 · Motion G00 G01 G02 G03 Group 02 · Plane G17 G18 G19 Group 03 · Distance G90 G91 Group 05/06 · Feed & Units G94 G95 G20 G21 Group 07 · Cutter comp G40 G41 G42 Group 14 · Work offset G54 G55 G56 G57 G58 G59

Each modal group holds exactly one active code (highlighted); programming another member of the same group replaces it.

That rule is why you can safely stack several G-codes in one block—as long as they come from different groups they do not fight. G17 G20 G90 is fine (three different groups). G00 G01 in one block is a conflict; on a Fanuc the later code simply wins, with no error. These are the groups you will actually use:

Group Controls Members Default at power-on*
Motion (01)How the tool movesG00 G01 G02 G03G00 or G01 (set by machine)
Plane (02)Which plane arcs & cycles work inG17 G18 G19G17 (XY)
Distance (03)Absolute vs incremental coordsG90 G91G90 (absolute)
Feed mode (05)Feed per minute vs per revG94 G95G94 (per minute)
Units (06)Inch vs metric inputG20 G21Last set (survives power-off)
Cutter comp (07)Tool radius compensationG40 G41 G42G40 (off)
Tool length (08)Tool length offsetG43 G44 G49G49 (off)
Canned cycle (09)Drilling/boring/tapping cyclesG73 G76 G81–G89 G80G80 (cancel)
Work offset (14)Which part-zero is activeG54 G55 G56 G57 G58 G59G54

*The group numbers above are Fanuc's internal labels and the defaults are typical—a machine builder can change them with a parameter, so confirm the power-on state for each machine you run. The concept (one active code per group, new replaces old) is the same on every ISO-style control. Note that the "one-shot" codes—dwell G04, the home-return codes G28/G30, machine-coordinate G53—live in a non-modal group (00) and do not stick around.

The Common G-Codes

You do not need to memorize the whole book. This grouped list is the set a beginner meets first—learn these and you can read the majority of milling programs. (Canned cycles like G81/G83 get their own treatment; see Canned Cycles.)

Code What it does
Motion
G00Rapid—move to a position as fast as possible (positioning, not cutting)
G01Linear feed—move in a straight line at the programmed feedrate (cutting)
G02Circular feed, clockwise arc
G03Circular feed, counterclockwise arc
Dwell (non-modal)
G04Dwell—pause for a set time (e.g. G04 P1000 = 1 second). Its own block.
Plane / Units / Distance
G17 / G18 / G19Select the working plane: XY / ZX / YZ
G20 / G21Inch input / metric input
G90 / G91Absolute / incremental coordinates
G94 / G95Feed per minute / feed per revolution
Coordinates & offsets
G28Return to machine home (reference point), usually via an intermediate point
G53Move in machine coordinates for this block only (ignores work offset)
G54–G59Select work coordinate system 1–6 (your part zero)
G43 / G49Apply tool length offset (with an H number) / cancel it
G40 / G41 / G42Cutter radius comp off / left / right (with a D number)

Work offsets (G54–G59) and tool length offset (G43) are the bridge between your program's numbers and where the part physically sits in the machine—that whole subject is covered in Coordinate Systems & Work Offsets.

The Common M-Codes

One caution before the table: M-codes are far less standardized than G-codes. The core flow and spindle codes below are near-universal, but many M-codes are assigned by the machine builder and mean nothing on another machine. Always keep the M-code list from your machine's manual handy.

Code What it does
Program flow
M00Mandatory program stop—machine halts until the operator presses Cycle Start
M01Optional stop—stops only if the Optional Stop switch is on
M02End of program (older form, no rewind)
M30End of program with reset and rewind back to the top (the usual ending)
Spindle
M03Spindle on, clockwise (normal)
M04Spindle on, counterclockwise (reverse)
M05Spindle stop
M19Orient the spindle to a fixed angle (needed for tool changes and back-boring)
Tool & coolant
M06Tool change—swap in the tool selected by the T word
M08Flood coolant on
M09Coolant off
Subprograms
M98Call a subprogram (M98 P____ = call that program number)
M99End of subprogram / return to the caller (also ends a macro)
M198Call a subprogram stored on an external device (drip-feed / DNC)

Subprograms (M98/M99) let you write a hole pattern or toolpath once and reuse it—the first real step toward automation and, eventually, macros.

Feeds, Speeds, Units, and Direction

Two words control how aggressively the machine cuts:

  • S = spindle speed in RPM. S1500 M03 spins the tool at 1500 RPM clockwise. S sets the number; M03/M04/M05 actually start or stop it.
  • F = feedrate, how fast the tool advances through the material. Under G94 that is distance per minute (inch/min or mm/min); under G95 it is distance per spindle revolution.

Feedrate only applies to feed moves (G01/G02/G03). Rapid moves (G00) ignore F and run at the machine's maximum traverse rate—which is exactly why you never rapid into the part.

Inch vs metric is set by G20 (inch) / G21 (metric). This is not cosmetic: it changes what every coordinate means. X2.5 is two-and-a-half inches under G20 and two-and-a-half millimeters under G21. Set it once at the top and never assume—it is one of the modes that survives a power cycle.

Absolute (G90) vs incremental (G91) changes what coordinates count from. In absolute, every X/Y/Z is a position measured from part zero. In incremental, every X/Y/Z is a distance to move from where the tool is right now. The same two moves, written both ways:

(ABSOLUTE - coordinates are positions from part zero)
G90 G00 X1.0 Y1.0    (go to the point 1.0, 1.0)
X3.0 Y1.0            (go to the point 3.0, 1.0)

(INCREMENTAL - coordinates are distances from here)
G91 G00 X1.0 Y1.0    (move +1.0 in X and +1.0 in Y)
X2.0 Y0              (move +2.0 in X, 0 in Y -> lands at the same spot)

Both reach the same place. Beginners should default to absolute (G90)—a single wrong number in incremental compounds into every move after it.

Your First Complete Program

Here is a whole, runnable program that drills one hole in the top of a plate, with part zero at the lower-left corner and the top face. It is deliberately small so you can see the shape of a complete program—setup, the work, and a clean shutdown—end to end. Read it once, then read the line-by-line notes.

%
O0001 (DRILL ONE HOLE)
N10 G20 G17 G40 G49 G80 G90     (SAFE START LINE)
N20 G54                         (SELECT PART ZERO)
N30 T1 M06                      (PUT TOOL 1 IN THE SPINDLE)
N40 S1500 M03                   (SPINDLE ON CW, 1500 RPM)
N50 G00 X1.0 Y1.0               (RAPID ABOVE THE HOLE)
N60 G43 H01 Z0.5 M08            (TOOL LENGTH ON, RAPID TO 0.5 ABOVE, COOLANT ON)
N70 G01 Z-0.25 F5.0             (FEED DOWN TO -0.25 DEEP AT 5 IN/MIN)
N80 G00 Z0.5 M09                (RAPID OUT OF THE HOLE, COOLANT OFF)
N90 G91 G28 Z0                  (RETURN Z TO MACHINE HOME)
N100 M05                        (SPINDLE STOP)
N110 M30                        (PROGRAM END AND REWIND)
%
Block Line by line
% / O0001File-start marker, then the program number and a comment naming it.
N10The safe start line. It forces the dangerous modal groups to known values before anything moves: inch (G20), XY plane (G17), cutter comp off (G40), length comp off (G49), canned cycle off (G80), absolute (G90). This is your insurance against leftover modes from the last program.
N20Select work coordinate system G54—the part zero you touched off on the machine.
N30Load tool 1. T1 selects it, M06 performs the change.
N40Set 1500 RPM and start the spindle clockwise. Note S and M03 together.
N50Rapid (G00) to a safe point directly over the hole. Z has not moved down yet.
N60Activate tool length offset (G43 with height register H01), rapid down to 0.5 above the surface, and turn coolant on (M08).
N70The actual cut: feed (G01) straight down to 0.25 deep at 5 in/min. This is the only F in the program—it stays modal but nothing else uses it.
N80Rapid back up clear of the part and shut coolant off.
N90Send Z to machine home. G91 makes the G28 move incremental so it is safe regardless of position; G28 Z0 means "go home in Z through the current point."
N100–N110Stop the spindle, then end the program and rewind (M30).

That is the skeleton every milling program shares: safe start → pick offset and tool → spindle on → get above the work → length offset + approach + cut → retract → go home → end. Real programs add more tools and more cuts, but the frame stays the same.

Where Dialects Differ

Everything above is Fanuc / ISO style, the most common family and the baseline the rest of this wiki assumes. Most controls—Haas, Mazak's EIA/ISO mode, Mitsubishi, and Fanuc itself—speak very close to this dialect, with small differences in optional codes. But two big families are genuinely different animals:

  • Siemens SINUMERIK uses named programs instead of O-numbers, calls tools by name, and runs canned cycles as function calls (CYCLE81(...)) rather than G-codes. It can also run a Fanuc-style ISO mode. See Siemens ISO Mode and Sinumerik Programming Basics.
  • Heidenhain Klartext is a conversational, plain-language format built around L (line) and CC/C (arc) blocks and Q-parameters—it looks nothing like G-code at a glance, though Heidenhain controls also accept ISO. See the Heidenhain Series Guide.

Even where the syntax diverges, the concepts on this page—modal state, work offsets, feeds and speeds, cutter comp—carry straight over. Learn them once here and every control gets easier.

Next steps once this clicks: Coordinate Systems & Work Offsets (where part zero comes from), Canned Cycles (drilling and boring in one line), and Intro to CNC Macros (when you want variables and logic instead of fixed numbers).

References

  • Peter Smid, Fanuc CNC Custom Macros (Ch. 1–3: Review of G-codes, M-codes and Subprograms), Industrial Press, 2005.
  • Fanuc, Operator’s Manual (Preparatory Function and Miscellaneous Function chapters), FANUC Corporation.

Have a question or want to contribute?

Contact us with corrections, additions, or topics you'd like covered.

Get in Touch