diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,12 @@
+1.3.0.0
+=======
+
+* Default input file name is now `input.json`, not `<template name>_input.json`.
+
+* Changed recommended way of reading input via `Helper.hs`
+
+* Added flag `preserve-temp` to not nuke temporary files after execution.
+
 1.2.3.0
 =======
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -46,68 +46,88 @@
 
 * `template_input.json` - Input data for template in JSON format.
 
-``` JSON
-{
-  "line-width": 2,
-  "spiral-precision": 0.01,
-  "spiral-interval": [0,4],
-  "spiral-a": 0.1,
-  "spiral-b": 4
-}
-```
+  ``` JSON
+  {
+    "line-width": 2,
+    "spiral-precision": 0.01,
+    "spiral-interval": [0,4],
+    "spiral-a": 0.1,
+    "spiral-b": 4
+  }
+  ```
 
 * `template.htex` - TeX/LaTeX with embedded Haskell that reads input data from
 file `template.json`. You have to provide code at the beginning of file that reads
 the inputs, like that:
 
-``` Haskell
-\begin{document}
+  Make a `Helper.hs` file in directory with template:
+  ``` haskell
+  module Helper where
 
-\begin{haskellpragmas}
-{-# LANGUAGE OverloadedStrings #-}
-\end{haskellpragmas}
-\begin{writehaskell}
-import Data.Aeson
-import System.IO.Unsafe (unsafePerformIO)
-import qualified Data.ByteString.Lazy as BS
+  import qualified Data.ByteString.Lazy as BS
+  import Data.Aeson
+  import System.IO.Unsafe
 
-data Input = Input {
-  lineWidth       :: Double
-, spiralPrecision :: Double
-, spiralInterval  :: (Double, Double)
-, spiralA         :: Double
-, spiralB         :: Double
-}
+  defaultInput :: FromJSON a => a
+  {-# NOINLINE defaultInput #-}
+  defaultInput = case unsafePerformIO $ fmap eitherDecode' $ BS.readFile "input.json" of
+    Left e -> error (show e)
+    Right a -> a
+  ```
 
-instance FromJSON Input where
-  parseJSON (Object o) = Input
-    <$> o .: "line-width"
-    <*> o .: "spiral-precision"
-    <*> o .: "spiral-interval"
-    <*> o .: "spiral-a"
-    <*> o .: "spiral-b"
+  Next in your `.htex` file:
+  ``` Haskell
+  \begin{document}
 
-inpt :: Input
-inpt = case unsafePerformIO $ fmap eitherDecode' $ BS.readFile "template_input.json" of
-  Left e -> error (show e)
-  Right a -> a
+  \begin{haskellpragmas}
+  {-# LANGUAGE OverloadedStrings #-}
+  \end{haskellpragmas}
+  \begin{writehaskell}
+  import Data.Aeson
+  import Helper
 
-\end{writehaskell}
-```
+  data Input = Input {
+    lineWidth       :: Double
+  , spiralPrecision :: Double
+  , spiralInterval  :: (Double, Double)
+  , spiralA         :: Double
+  , spiralB         :: Double
+  }
 
-Note: The tool copies JSON with inputs to build folder with .htex twice, once with
-name specified at `input` key in template description and secondly at fixed `<template_name>_input.json`.
+  instance FromJSON Input where
+    parseJSON (Object o) = Input
+      <$> o .: "line-width"
+      <*> o .: "spiral-precision"
+      <*> o .: "spiral-interval"
+      <*> o .: "spiral-a"
+      <*> o .: "spiral-b"
 
+  inpt :: Input
+  inpt = defaultInput
+  \end{writehaskell}
+  ```
+
+  Note: The tool copies JSON with inputs to build folder with .htex twice, once with
+  name specified at `input` key in template description and secondly at fixed `input.json`.
+
 * `template.yaml` - description of template and its dependencies.
 
-``` YAML
-name:  template01             # name of template
-input: template01_input.json  # name of input file
-body:  template01.htex        # name of .htex file
-dependencies: {}              # dependency tree (see below)
-haskintex-opts: []            # additional flags to haskintex
-```
+  ``` YAML
+  name:  template01             # name of template
+  input: template01_input.json  # name of input file
+  body:  template01.htex        # name of .htex file
+  dependencies: {}              # dependency tree (see below)
+  haskintex-opts: []            # additional flags to haskintex
+  ```
 
+  For input `Helper.hs` you should make a record to inform `pdf-slave` that the module should be copied to build directory:
+
+  ``` YAML
+  dependencies:
+    Helper.hs:
+      type: other
+  ```
+
 ## Dependencies
 
 There are 4 different types of dependencies:
@@ -310,3 +330,11 @@
   ```
 
 3. Or download [precompiled container](https://hub.docker.com/r/ncrashed/pdf-slave/) from Docker Hub.
+
+
+Credits
+=======
+
+* Daniel Díaz - author of `haskintex` tool that is core of the package.
+
+* Alexander Vershilov aka qnikst - help with debugging and new `Helper.hs` module.
diff --git a/app/Main.hs b/app/Main.hs
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -33,13 +33,15 @@
 -- | CLI options
 data Options = Options {
   -- | Path to template file, if missing, stdin is used
-  templatePath  :: Maybe FilePath
+  templatePath       :: Maybe FilePath
   -- | Path to output pdf file, if missing, stdout is used
-, pdfOutputPath :: Maybe FilePath
+, pdfOutputPath      :: Maybe FilePath
   -- | Path to JSON input file for overwritting input data of bundle
 , inputOverwritePath :: Maybe FilePath
+  -- | If the flag is set, temporary dirs won't be nuked after execution
+, preserveTempDirs   :: Bool
   -- | CLI action
-, cliCommand    ::  Command
+, cliCommand         :: Command
 }
 
 -- | Same as 'strOption' but parses Text
@@ -65,6 +67,10 @@
       <> " for bundle or template input file" )
     <> metavar "INPUT_JSON_PATH"
     )
+  <*> switch (
+       long "preserve-temp"
+    <> help "If the flag is set, temporary dirs won't be nuked after execution"
+    )
   <*> commandParser
 
 -- | Parser of CLI commands
@@ -110,12 +116,12 @@
         bs <- case res of
           Left bundle -> do
             let bundle' = fromMaybe bundle $ (\i -> bundle { templateInput = i }) <$> optInput
-            renderBundleToPDF bundle'
+            renderBundleToPDF bundle' nuke
           Right template -> do
             inputOverwrite <- sequence $ fmap toTextWarn inputOverwritePath
             let template' = fromMaybe template $
                   (const $ template { templateFileInput = inputOverwrite }) <$> optInput
-            renderTemplateToPDF template' baseDir
+            renderTemplateToPDF template' baseDir nuke
         -- output results
         case pdfOutputPath of
           Nothing -> liftIO $ BS.putStr bs
@@ -150,6 +156,8 @@
             outputFolder' <- toTextWarn outputFolder
             echo $ "Bundle is unpacked to " <> outputFolder'
       _ -> return ()
+
+  nuke = not preserveTempDirs
 
 main :: IO ()
 main = execParser opts >>= pdfSlave
diff --git a/pdf-slave.cabal b/pdf-slave.cabal
--- a/pdf-slave.cabal
+++ b/pdf-slave.cabal
@@ -1,5 +1,5 @@
 name:                pdf-slave
-version:             1.2.3.0
+version:             1.3.0.0
 synopsis:            Tool to generate PDF from haskintex templates and YAML input
 description:         Please see README.md
 homepage:            https://github.com/NCrashed/pdf-slave#readme
@@ -31,6 +31,7 @@
     , base64-bytestring        >= 1.0      && < 1.1
     , bytestring               >= 0.10     && < 0.11
     , containers               >= 0.5      && < 0.6
+    , directory                >= 1.2      && < 1.3
     , exceptions               >= 0.8      && < 0.9
     , haskintex                >= 0.6      && < 0.8
     , HaTeX                    >= 3.16     && < 3.18
@@ -39,6 +40,7 @@
     , system-filepath          >= 0.4      && < 0.5
     , unordered-containers     >= 0.2      && < 0.3
     , yaml                     >= 0.8      && < 0.9
+
   default-extensions:
     DeriveGeneric
     LambdaCase
diff --git a/src/Text/PDF/Slave/Render.hs b/src/Text/PDF/Slave/Render.hs
--- a/src/Text/PDF/Slave/Render.hs
+++ b/src/Text/PDF/Slave/Render.hs
@@ -20,19 +20,25 @@
   , parseBundleOrTemplateFromFile
   ) where
 
+import Control.Concurrent
 import Control.Monad (join, forM_)
 import Control.Monad.Catch
 import Data.Aeson (Value(..))
 import Data.ByteString (ByteString)
+import Data.Char
 import Data.Maybe (fromMaybe)
 import Data.Monoid
 import Data.Set (Set)
 import Data.Yaml (ParseException, decodeEither')
 import Filesystem.Path (dropExtension, directory)
+import Filesystem.Path.CurrentOS (decodeString)
 import GHC.Generics
 import Prelude hiding (FilePath)
 import Shelly
+import System.IO (hClose, openTempFile)
 
+import System.Directory (getTemporaryDirectory)
+
 import qualified Data.Aeson as A
 import qualified Data.ByteString.Lazy as BZ
 import qualified Data.Foldable as F
@@ -73,15 +79,16 @@
 renderBundleOrTemplateFromFile ::
      FilePath -- ^ Path to either bundle 'Template' or template 'TemplateFile'
   -> Maybe Value -- ^ Overwrite of input JSON for bundle
+  -> Bool -- ^ Nuke temp folder?
   -> Sh PDFContent
-renderBundleOrTemplateFromFile filename bundleInput = do
+renderBundleOrTemplateFromFile filename bundleInput nuke = do
   res <- parseBundleOrTemplateFromFile filename
   let baseDir = directory filename
   case res of
     Left bundle -> do
       let bundle' = fromMaybe bundle $ fmap (\i -> bundle { templateInput = Just i }) bundleInput
-      renderBundleToPDF bundle'
-    Right template -> renderTemplateToPDF template baseDir
+      renderBundleToPDF bundle' nuke
+    Right template -> renderTemplateToPDF template baseDir nuke
 
 -- | Try to parse either a bundle or template file
 parseBundleOrTemplateFromFile :: FilePath -- ^ Path to either 'Template' or 'TemplateFile'
@@ -102,36 +109,40 @@
 -- | Helper to render from all-in bundle template
 renderFromFileBundleToPDF :: FilePath -- ^ Path to 'Template' all-in bundle
   -> Maybe Value -- ^ Overwrite of input JSON for bundle
+  -> Bool -- ^ Nuke temp folder?
   -> Sh PDFContent
-renderFromFileBundleToPDF filename bundleInput = do
+renderFromFileBundleToPDF filename bundleInput nuke = do
   cnt <- readBinary filename
   case decodeEither' cnt of
     Left e -> throwM $ BundleFormatError filename e
     Right bundle -> do
       let bundle' = fromMaybe bundle $ fmap (\i -> bundle { templateInput = Just i }) bundleInput
-      renderBundleToPDF bundle'
+      renderBundleToPDF bundle' nuke
 
 -- | Helper to render from template file
 renderFromFileToPDF :: FilePath -- ^ Path to 'TemplateFile'
+  -> Bool -- ^ Nuke temp folder?
   -> Sh PDFContent
-renderFromFileToPDF filename = do
+renderFromFileToPDF filename nuke = do
   cnt <- readBinary filename
   case decodeEither' cnt of
     Left e -> throwM $ TemplateFormatError filename e
-    Right template -> renderTemplateToPDF template (directory filename)
+    Right template -> renderTemplateToPDF template (directory filename) nuke
 
 -- | Unpack bundle, render the template, cleanup and return PDF
 renderBundleToPDF :: Template -- ^ Input all-in template
+  -> Bool -- ^ Nuke temp folder?
   -> Sh PDFContent
-renderBundleToPDF bundle = withTmpDir $ \unpackDir -> do
+renderBundleToPDF bundle nuke = withTmpDir' nuke $ \unpackDir -> do
   template <- storeTemplateInFiles bundle unpackDir
-  renderTemplateToPDF template unpackDir
+  renderTemplateToPDF template unpackDir nuke
 
 -- | Render template and return content of resulted PDF file
 renderTemplateToPDF :: TemplateFile -- ^ Input template
   -> FilePath -- ^ Base directory
+  -> Bool -- ^ Nuke temp folder?
   -> Sh PDFContent -- ^ Output PDF file
-renderTemplateToPDF t@TemplateFile{..} baseDir = withTmpDir $ \outputFolder -> do
+renderTemplateToPDF t@TemplateFile{..} baseDir nuke = withTmpDir' nuke $ \outputFolder -> do
   -- Parse global input file and pass it as inherited input
   minput <- case templateFileInput of
     Nothing -> return Nothing
@@ -185,7 +196,7 @@
         , toTextArg $ baseDir </> bodyName ]
         ++ templateFileHaskintexOpts
   -- input file might be missing, if missing we can inject input from parent
-  let outputFixedInputName = outputFolder </> (templateFileName <> "_input") <.> "json"
+  let outputFixedInputName = outputFolder </> (("input" :: FilePath) <.> "json")
   case templateFileInput of
     Nothing -> whenJust minput $ \input -> do
       writeBinary outputFixedInputName $ BZ.toStrict . A.encode $ input
@@ -287,7 +298,7 @@
   relInputName <- case templateInput of
     Nothing -> return Nothing
     Just input -> do
-      let inputName = folder </> (templateName <> "_input") <.> "json"
+      let inputName = folder </> ("input" :: FilePath) <.> "json"
       writeBinary inputName $ BZ.toStrict $ A.encode input
       fmap Just $ relativeTo folder inputName
   let bodyName = folder </> templateName <.> "htex"
@@ -324,3 +335,19 @@
         mkdir_p $ directory bodyName
         writeBinary bodyName body
         return OtherDepFile
+
+-- | Create a temporary directory and pass it as a parameter to a Sh
+-- computation. The directory is nuked afterwards if first parameter is 'True'.
+withTmpDir' :: Bool -> (FilePath -> Sh a) -> Sh a
+withTmpDir' nuke act = do
+  trace "withTmpDir"
+  dir <- liftIO getTemporaryDirectory
+  tid <- liftIO myThreadId
+  (pS, fhandle) <- liftIO $ openTempFile dir ("tmp" ++ filter isAlphaNum (show tid))
+  let p = decodeString pS
+  liftIO $ hClose fhandle -- required on windows
+  rm_f p
+  mkdir p
+  if nuke
+    then act p `finally_sh` rm_rf p
+    else act p
