diff --git a/src/main/java/ch/fritteli/labyrinth/HTMLFileRenderer.java b/src/main/java/ch/fritteli/labyrinth/HTMLFileRenderer.java
index 85decec..04d7d79 100644
--- a/src/main/java/ch/fritteli/labyrinth/HTMLFileRenderer.java
+++ b/src/main/java/ch/fritteli/labyrinth/HTMLFileRenderer.java
@@ -1,17 +1,15 @@
 package ch.fritteli.labyrinth;
 
 import lombok.NonNull;
-import lombok.Setter;
 
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.StandardOpenOption;
 
 public class HTMLFileRenderer implements Renderer<Path> {
     @NonNull
     private static final HTMLRenderer HTML_RENDERER = HTMLRenderer.newInstance();
-    @Setter
     private Path targetFile;
 
     private HTMLFileRenderer() {
@@ -32,14 +30,24 @@ public class HTMLFileRenderer implements Renderer<Path> {
         return this.targetFile != null && this.targetFile.toFile().canWrite();
     }
 
+    @NonNull
+    public HTMLFileRenderer setTargetFile(@NonNull final Path targetFile) {
+        this.targetFile = targetFile;
+        return this;
+    }
+
     @Override
     public Path render(@NonNull final Labyrinth labyrinth) {
         if (!this.isTargetFileDefinedAndWritable()) {
-            throw new IllegalArgumentException("Cannot write to target file. See previous log messages for details.");
+            try {
+                Files.createFile(this.targetFile);
+            } catch (IOException e) {
+                throw new IllegalArgumentException("Cannot write to target file.", e);
+            }
         }
         final String html = HTML_RENDERER.render(labyrinth);
         try {
-            Files.writeString(this.targetFile, html, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE);
+            Files.writeString(this.targetFile, html, StandardCharsets.UTF_8);
         } catch (IOException e) {
             System.err.println("Failed writing to file " + this.targetFile.normalize().toString());
             e.printStackTrace();
diff --git a/src/main/java/ch/fritteli/labyrinth/Main.java b/src/main/java/ch/fritteli/labyrinth/Main.java
index c38c796..ff3821a 100644
--- a/src/main/java/ch/fritteli/labyrinth/Main.java
+++ b/src/main/java/ch/fritteli/labyrinth/Main.java
@@ -2,16 +2,31 @@ package ch.fritteli.labyrinth;
 
 import lombok.NonNull;
 
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
 public class Main {
     public static void main(@NonNull final String[] args) {
-        int width = 100;
-        int height = 100;
+        int width = 80;
+        int height = 40;
         final Labyrinth labyrinth = new Labyrinth(width, height);
         final TextRenderer textRenderer = TextRenderer.newInstance();
-        System.out.println(textRenderer.render(labyrinth));
-        System.out.println(textRenderer.setRenderSolution(true).render(labyrinth));
         final HTMLRenderer htmlRenderer = HTMLRenderer.newInstance();
+        final Path userHome = Paths.get(System.getProperty("user.home"));
+        final TextFileRenderer textFileRenderer = TextFileRenderer.newInstance()
+                .setTargetLabyrinthFile(userHome.resolve("labyrinth.txt"))
+                .setTargetSolutionFile(userHome.resolve("labyrinth-solution.txt"));
+        final HTMLFileRenderer htmlFileRenderer = HTMLFileRenderer.newInstance()
+                .setTargetFile(userHome.resolve("labyrinth.html"));
+        // Render Labyrinth to stdout
+        System.out.println(textRenderer.render(labyrinth));
+        // Render Labyrinth solution to stdout
+        System.out.println(textRenderer.setRenderSolution(true).render(labyrinth));
+        // Render HTML to stdout
         System.out.println(htmlRenderer.render(labyrinth));
-        System.out.println(HTMLFileRenderer.newInstance().render(labyrinth));
+        // Render Labyrinth and solution to (separate) files
+        System.out.println(textFileRenderer.render(labyrinth));
+        // Render HTML to file
+        System.out.println(htmlFileRenderer.render(labyrinth));
     }
 }
diff --git a/src/main/java/ch/fritteli/labyrinth/TextFileRenderer.java b/src/main/java/ch/fritteli/labyrinth/TextFileRenderer.java
new file mode 100644
index 0000000..64191bf
--- /dev/null
+++ b/src/main/java/ch/fritteli/labyrinth/TextFileRenderer.java
@@ -0,0 +1,85 @@
+package ch.fritteli.labyrinth;
+
+import io.vavr.collection.List;
+import lombok.NonNull;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+public class TextFileRenderer implements Renderer<List<Path>> {
+    @NonNull
+    private static final TextRenderer TEXT_RENDERER = TextRenderer.newInstance();
+    private Path targetLabyrinthFile;
+    private Path targetSolutionFile;
+
+    private TextFileRenderer() {
+        try {
+            this.targetLabyrinthFile = Files.createTempFile("labyrinth_", ".txt");
+            this.targetSolutionFile = this.targetLabyrinthFile.getParent().resolve(
+                    this.targetLabyrinthFile.getFileName().toString().replace(".txt", "-solution.txt")
+            );
+        } catch (IOException e) {
+            System.err.println("Unable to set default target file.");
+            e.printStackTrace();
+        }
+    }
+
+    @NonNull
+    public static TextFileRenderer newInstance() {
+        return new TextFileRenderer();
+    }
+
+    public boolean isTargetLabyrinthFileDefinedAndWritable() {
+        return this.targetLabyrinthFile != null && this.targetLabyrinthFile.toFile().canWrite();
+    }
+
+    public boolean isTargetSolutionFileDefinedAndWritable() {
+        return this.targetSolutionFile != null && this.targetSolutionFile.toFile().canWrite();
+    }
+
+    @NonNull
+    public TextFileRenderer setTargetLabyrinthFile(@NonNull final Path targetLabyrinthFile) {
+        this.targetLabyrinthFile = targetLabyrinthFile;
+        return this;
+    }
+
+    @NonNull
+    public TextFileRenderer setTargetSolutionFile(@NonNull final Path targetSolutionFile) {
+        this.targetSolutionFile = targetSolutionFile;
+        return this;
+    }
+
+    @Override
+    public List<Path> render(@NonNull final Labyrinth labyrinth) {
+        if (!this.isTargetLabyrinthFileDefinedAndWritable()) {
+            try {
+                Files.createFile(this.targetLabyrinthFile);
+            } catch (IOException e) {
+                throw new IllegalArgumentException("Cannot write to target labyrinth file.", e);
+            }
+        }
+        if (!this.isTargetSolutionFileDefinedAndWritable()) {
+            try {
+                Files.createFile(this.targetSolutionFile);
+            } catch (IOException e) {
+                throw new IllegalArgumentException("Cannot write to target solution file.", e);
+            }
+        }
+        final String text;
+        final String solution;
+        synchronized (TEXT_RENDERER) {
+            text = TEXT_RENDERER.setRenderSolution(false).render(labyrinth).strip();
+            solution = TEXT_RENDERER.setRenderSolution(true).render(labyrinth).strip();
+        }
+        try {
+            Files.write(this.targetLabyrinthFile, text.getBytes(StandardCharsets.UTF_8));
+            Files.write(this.targetSolutionFile, solution.getBytes(StandardCharsets.UTF_8));
+        } catch (IOException e) {
+            System.err.println("Failed writing to file " + this.targetLabyrinthFile.normalize().toString());
+            e.printStackTrace();
+        }
+        return List.of(this.targetLabyrinthFile, this.targetSolutionFile);
+    }
+}