diff --git a/corsika/detail/output/NoOutput.inl b/corsika/detail/output/NoOutput.inl
new file mode 100644
index 0000000000000000000000000000000000000000..6fc84aa5e74028994cd3bf065a1a7fff892cd19c
--- /dev/null
+++ b/corsika/detail/output/NoOutput.inl
@@ -0,0 +1,30 @@
+/*
+ * (c) Copyright 2021 CORSIKA Project, corsika-project@lists.kit.edu
+ *
+ * This software is distributed under the terms of the GNU General Public
+ * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
+ * the license.
+ */
+#pragma once
+
+namespace corsika {
+
+  NoOutput::NoOutput()
+      : {}
+
+  void NoOutput::startOfRun(std::filesystem::path const& directory) {}
+
+  void NoOutput::startOfEvent() {}
+
+  void NoOutput::endOfEvent() {}
+
+  void NoOutput::endOfRun() {}
+
+  YAML::Node NoOutput::getConfig() const { return YAML::Node(); }
+
+  YAML::Node NoOutput::getFinalOutput() const { return YAML::Node(); }
+
+  template <typename... TVArgs>
+  void NoOutput::write(TVArgs&& args...) {}
+
+} // namespace corsika
diff --git a/corsika/output/NoOutput.hpp b/corsika/output/NoOutput.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..a5fe1160c3f5d1744de76d0b618ff4079a24142b
--- /dev/null
+++ b/corsika/output/NoOutput.hpp
@@ -0,0 +1,66 @@
+/*
+ * (c) Copyright 2021 CORSIKA Project, corsika-project@lists.kit.edu
+ *
+ * This software is distributed under the terms of the GNU General Public
+ * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
+ * the license.
+ */
+#pragma once
+
+#include <corsika/output/BaseOutput.hpp>
+
+namespace corsika {
+
+  /**
+   * This class can be used as a drop-in for any output template
+   * and doesn't write *any* output files.
+   *
+   */
+  class NoOutput : public BaseOutput {
+
+  public:
+    /**
+     * Construct a blank output.
+     */
+    NoOutput();
+
+    /**
+     * Called at the start of each run.
+     */
+    virtual void startOfRun(std::filesystem::path const& directory) final override;
+
+    /**
+     * Called at the start of each event/shower.
+     */
+    virtual void startOfEvent() final override;
+
+    /**
+     * Called at the end of each event/shower.
+     */
+    virtual void endOfEvent() final override;
+
+    /**
+     * Called at the end of each run.
+     */
+    virtual void endOfRun() final override;
+
+    /**
+     * Get the configuration of this output.
+     */
+    virtual YAML::Node getConfig() const final override;
+
+    /**
+     * Accept any arguments and ignore them.
+     */
+    template <typename... TVArgs>
+    void write(TVArgs&& args...);
+
+    /**
+     * Get final text outputs for the config file.
+     */
+    virtual YAML::Node getFinalOutput() const final override;
+  };
+
+} // namespace corsika
+
+#include <corsika/detail/output/NoOutput.inl>