diff --git a/swaymsg/main.c b/swaymsg/main.c
index b58c673c..02bb12c6 100644
--- a/swaymsg/main.c
+++ b/swaymsg/main.c
@@ -288,6 +288,51 @@ static void pretty_print_config(json_object *c) {
 	printf("%s\n", json_object_get_string(config));
 }
 
+static void pretty_print_tree(json_object *obj, int indent) {
+	for (int i = 0; i < indent; i++) {
+		printf("  ");
+	}
+
+	int id = json_object_get_int(json_object_object_get(obj, "id"));
+	const char *name = json_object_get_string(json_object_object_get(obj, "name"));
+	const char *type = json_object_get_string(json_object_object_get(obj, "type"));
+	const char *shell = json_object_get_string(json_object_object_get(obj, "shell"));
+
+	printf("#%d: %s \"%s\"", id, type, name);
+
+	if (shell != NULL) {
+		int pid = json_object_get_int(json_object_object_get(obj, "pid"));
+		const char *app_id = json_object_get_string(json_object_object_get(obj, "app_id"));
+		json_object *window_props_obj = json_object_object_get(obj, "window_properties");
+		const char *instance = json_object_get_string(json_object_object_get(window_props_obj, "instance"));
+		const char *class = json_object_get_string(json_object_object_get(window_props_obj, "class"));
+		int x11_id = json_object_get_int(json_object_object_get(obj, "window"));
+
+		printf(" (%s, pid: %d", shell, pid);
+		if (app_id != NULL) {
+			printf(", app_id: \"%s\"", app_id);
+		}
+		if (instance != NULL) {
+			printf(", instance: \"%s\"", instance);
+		}
+		if (class != NULL) {
+			printf(", class: \"%s\"", class);
+		}
+		if (x11_id != 0) {
+			printf(", X11 window: 0x%X", x11_id);
+		}
+		printf(")");
+	}
+
+	printf("\n");
+
+	json_object *nodes_obj = json_object_object_get(obj, "nodes");
+	size_t len = json_object_array_length(nodes_obj);
+	for (size_t i = 0; i < len; i++) {
+		pretty_print_tree(json_object_array_get_idx(nodes_obj, i), indent + 1);
+	}
+}
+
 static void pretty_print(int type, json_object *resp) {
 	switch (type) {
 	case IPC_SEND_TICK:
@@ -298,6 +343,9 @@ static void pretty_print(int type, json_object *resp) {
 	case IPC_GET_CONFIG:
 		pretty_print_config(resp);
 		return;
+	case IPC_GET_TREE:
+		pretty_print_tree(resp, 0);
+		return;
 	case IPC_COMMAND:
 	case IPC_GET_WORKSPACES:
 	case IPC_GET_INPUTS: