diff --git a/Nibriboard/ClientFiles/BoardWindow.js b/Nibriboard/ClientFiles/BoardWindow.js
index dbb47ca..39427fa 100644
--- a/Nibriboard/ClientFiles/BoardWindow.js
+++ b/Nibriboard/ClientFiles/BoardWindow.js
@@ -185,7 +185,7 @@ class BoardWindow extends EventEmitter
 		}).bind(this))
 		
 		// Keep the server up to date on our viewport and cursor position
-		this.cursorSyncer = new CursorSyncer(this.rippleLink, this.cursorUpdateFrequency)
+		this.cursorSyncer = new CursorSyncer(this, this.cursorUpdateFrequency)
 		
 		// RippleLink message bindings
 		
diff --git a/Nibriboard/ClientFiles/Chunk.js b/Nibriboard/ClientFiles/Chunk.js
index 28e028e..88e669a 100644
--- a/Nibriboard/ClientFiles/Chunk.js
+++ b/Nibriboard/ClientFiles/Chunk.js
@@ -1,5 +1,7 @@
 "use strict";
 
+import { point_line_distance_multi } from 'line-distance-calculator';
+
 /**
  * Represents a single chunk on a plane.
  * Note that this is the client's representation of the chunk, so it's likely
@@ -14,8 +16,11 @@ class Chunk
 	 */
 	constructor(inChunkRef, inSize)
 	{
+		/** @type {ChunkReference} */
 		this.chunkRef = inChunkRef;
+		/** @type {number} */
 		this.size = inSize;
+		/** @type {[ { Points: [Vector], Width: number, Color: string }] */
 		this.lines = [];
 	}
 	
@@ -62,6 +67,23 @@ class Chunk
 		return area.overlaps(area);
 	}
 	
+	/**
+	 * Fetches the last line segment that lies underneath the specified point.
+	 * Prefers lines drawn later to lines drawn earlier.
+	 * @param  {Vector} point The point to find the line underneath.
+	 * @return {object|null}       The first line (segment) that lies underneath the specified point, or null if one couldn't be found.
+	 */
+	getLineUnderPoint(point)
+	{
+		// Prefer lines that have been drawn later (i.e. on top)
+		for (let i = this.lines.length - 1; i > 0; i--) {
+			// If our distance to the line is less than half the width (i.e. 
+			// the radius), then we must be inside it
+			if(point_line_distance_multi(point, this.lines[i].Points) <= this.lines[i].Width / 2)
+				return this.lines[i];
+		}
+	}
+	
 	update(dt)
 	{
 		
diff --git a/Nibriboard/ClientFiles/CursorSyncer.js b/Nibriboard/ClientFiles/CursorSyncer.js
index 34f6ba2..eb3c0a1 100644
--- a/Nibriboard/ClientFiles/CursorSyncer.js
+++ b/Nibriboard/ClientFiles/CursorSyncer.js
@@ -1,11 +1,14 @@
 "use strict";
 
+import Vector from './Utilities/Vector.js';
+
 class CursorSyncer
 {
-	constructor(inRippleLink, syncFrequency)
+	constructor(inBoardWindow, syncFrequency)
 	{
+		this.boardWindow = inBoardWindow
 		// The ripple link we should send the cursor updates down
-		this.rippleLink = inRippleLink;
+		this.rippleLink = this.boardWindow.rippleLink;
 		// The target frequency in fps at we should send cursor updates.
 		this.cursorUpdateFrequency = syncFrequency;
 		
@@ -13,7 +16,10 @@ class CursorSyncer
 		// link connects
 		this.rippleLink.on("connect", this.setup.bind(this));
 		
-		this.cursorPosition = { X: 0, Y: 0 };
+		/** The current cursor position in screen-space. @type {Vector} */
+		this.cursorPosition = new Vector(0, 0);
+		/** The current cursor position in plane-space. @type {Vector} */
+		this.absCursorPosition = new Vector(0, 0);
 	}
 	
 	setup()
@@ -22,10 +28,11 @@ class CursorSyncer
 		this.lastCursorUpdate = 0;
 		
 		document.addEventListener("mousemove", (function(event) {
-			this.cursorPosition = {
-				X: event.clientX,
-				Y: event.clientY
-			};
+			this.cursorPosition.x = event.clientX;
+			this.cursorPosition.y = event.clientY;
+			
+			this.absCursorPosition.x = this.boardWindow.viewport.x + this.cursorPosition.x;
+			this.absCursorPosition.y = this.boardWindow.viewport.y + this.cursorPosition.y;
 			
 			setTimeout((function() {
 			    // Throttle the cursor updates we send to the server - a high
@@ -50,7 +57,10 @@ class CursorSyncer
 		// Update the server on the mouse's position
 		this.rippleLink.send({
 			"Event": "CursorPosition",
-			"AbsCursorPosition": this.cursorPosition
+			"AbsCursorPosition": {
+				X: Math.floor(this.absCursorPosition.x),
+				Y: Math.floor(this.absCursorPosition.y)
+			}
 		});
 	}
 }
diff --git a/Nibriboard/ClientFiles/Pencil.js b/Nibriboard/ClientFiles/Pencil.js
index 0607dc3..d590b71 100644
--- a/Nibriboard/ClientFiles/Pencil.js
+++ b/Nibriboard/ClientFiles/Pencil.js
@@ -3,6 +3,7 @@
 import cuid from "cuid";
 import { simplify_line } from "visvalingam-simplifier";
 
+import ChunkReference from './ChunkReference.js';
 import Vector from './Utilities/Vector';
 import Mouse from './Utilities/Mouse';
 
@@ -129,6 +130,21 @@ class Pencil
 				this.sendUnsent();
 				break;
 			
+			case "eraser":
+				let locRef = this.boardWin.cursorSyncer.absCursorPosition;
+				let hoverChunkRef = new ChunkReference(
+					this.boardWindow.currentPlaneName, 
+					Math.floor((this.boardWindow.viewport.x + this.mouse.position.x) / this.boardWindow.gridSize),
+					Math.floor((this.boardWindow.viewport.y + this.mouse.position.y) / this.boardWindow.gridSize)
+				);
+				
+				let hoverChunk = this.boardWindow.chunkCache.fetchChunk(hoverChunk);
+				if(hoverChunk == null)
+					break; // If it's null, then we haven't received it yet from the server
+				
+				let lineToErase = hoverChunk.getLineUnderPoint()
+				break;
+			
 			case "pan":
 				// handled by BoardWindow.handleCanvasMovement(event)
 				break;
diff --git a/Nibriboard/ClientFiles/images/icons/eraser.png b/Nibriboard/ClientFiles/images/icons/eraser.png
new file mode 100644
index 0000000..6e166ca
Binary files /dev/null and b/Nibriboard/ClientFiles/images/icons/eraser.png differ
diff --git a/Nibriboard/ClientFiles/index.html b/Nibriboard/ClientFiles/index.html
index e853006..745faf5 100644
--- a/Nibriboard/ClientFiles/index.html
+++ b/Nibriboard/ClientFiles/index.html
@@ -21,6 +21,7 @@
 			
 			<section class="tools">
 				<span class="tool-selector" data-tool-name="brush" title="Draw lines with a brush." data-selected><img src="images/icons/brush.png" aria-hidden="true" /></span>
+				<span class="tool-selector" data-tool-name="eraser" title="Erase lines. Remember that you can't undo/redo yet!"><img src="images/icons/eraser.png" aria-hidden="true" /></span>
 				<span class="tool-selector" data-tool-name="pan" title="Pan around the plane."><img src="images/icons/pan.png" aria-hidden="true" /></span>
 				<span class="tool-selector" data-tool-name="pointer" title="Point at things, but don't change them."><img src="images/icons/point.png" aria-hidden="true" /></span>
 			</section>
diff --git a/README.md b/README.md
index 57d8773..a50e8ae 100644
--- a/README.md
+++ b/README.md
@@ -47,7 +47,7 @@ Note that if you're intending to use Nibriboard over the internet or an untruste
  - Images:
      - [Transparent Square Tiles](https://www.toptal.com/designers/subtlepatterns/transparent-square-tiles/) from [subtlepatterns.com](https://subtlepatterns.com/)
      - Icons:
-         - [OpenIconic](https://useiconic.com/open) - brush, move -> pan, sun -> point
+         - [OpenIconic](https://useiconic.com/open) - brush, move -> pan, sun -> point, eraser -> delete
  - Future reference: Libraries I am considering
 	 - [Paper.js](http://paperjs.org/) - Client-side rendering
  - [IotWeb](http://sensaura.org/pages/tools/iotweb/) - Underlying HTTP / WebSocket server
