diff --git a/docs/User-Manual.md b/docs/User-Manual.md
index 1866bf05..5484dcd8 100644
--- a/docs/User-Manual.md
+++ b/docs/User-Manual.md
@@ -15,6 +15,10 @@ title: User Manual
- [Generated Files](#generated-files)
- [Interpreter](#interpreter)
- [Language Details](#language-details)
+- [Macros](#macros)
+ - [Syntax Rules](#syntax-rules)
+ - [Explicit Renaming](#explicit-renaming)
+ - [Debugging](#debugging)
- [Multithreaded Programming](#multithreaded-programming)
- [Thread Safety](#thread-safety)
- [Foreign Function Interface](#foreign-function-interface)
@@ -163,6 +167,50 @@ A [R7RS Compliance Chart](Scheme-Language-Compliance) lists differenc
[API Documentation](API) is available for the libraries provided by Cyclone.
+# Macros
+
+## Syntax Rules
+
+High-level hygienic macros may be created using `syntax-rules`. This system is based on a template language specified by R7RS. The specification goes into more detail on how to work with these macros:
+
+ (define-syntax when
+ (syntax-rules ()
+ ((when test result1 result2 ...)
+ (if test
+ (begin result1 result2 ...)))))
+
+## Explicit Renaming
+
+Alternatively a low-level explicit renaming (ER) system is provided that allows defining macros using Scheme code, in a similar manner as `defmacro`.
+
+This macro system provides the convenience functions `(rename identifier)` to hygienically rename an identifier and `(compare identifier1 identifier2)` to compare two identifiers:
+
+ (define-syntax when
+ (er-macro-transformer
+ (lambda (exp rename compare)
+ (if (null? (cdr exp)) (error/loc "empty when" exp))
+ (if (null? (cddr exp)) (error/loc "no when body" exp))
+ `(if ,(cadr exp)
+ ((lambda () ,@(cddr exp)))))))
+
+## Debugging
+
+- A file may be compiled with the `-t` option which will write all of the intermediate transformations - including macro expansions - out to the `.c` file.
+- From the interpreter one can use `expand`:
+
+ cyclone> (expand '(when #t (+ 1 2 3)))
+ (if #t ((lambda () (+ 1 2 3))) )
+
+- Alternatively when developing an ER macro, since its just a Scheme function, the macro can be defined as a `lambda` and passed a quoted expression to debug:
+
+ (pretty-print
+ ((lambda (exp rename compare)
+ (if (null? (cdr exp)) (error/loc "empty when" exp))
+ (if (null? (cddr exp)) (error/loc "no when body" exp))
+ `(if ,(cadr exp)
+ ((lambda () ,@(cddr exp)))))
+ '(when #t (write 1) (write 2)) #f #f))
+
# Multithreaded Programming
## Overview