diff --git a/src/libexpr/value-to-json.cc b/src/libexpr/value-to-json.cc
index 03504db61..4d63d8b49 100644
--- a/src/libexpr/value-to-json.cc
+++ b/src/libexpr/value-to-json.cc
@@ -10,7 +10,7 @@
 namespace nix {
 
 void printValueAsJSON(EvalState & state, bool strict,
-    Value & v, const PosIdx pos, JSONPlaceholder & out, PathSet & context)
+    Value & v, const PosIdx pos, JSONPlaceholder & out, PathSet & context, bool copyToStore)
 {
     checkInterrupt();
 
@@ -32,7 +32,10 @@ void printValueAsJSON(EvalState & state, bool strict,
             break;
 
         case nPath:
-            out.write(state.copyPathToStore(context, v.path));
+            if (copyToStore)
+                out.write(state.copyPathToStore(context, v.path));
+            else
+                out.write(v.path);
             break;
 
         case nNull:
@@ -54,10 +57,10 @@ void printValueAsJSON(EvalState & state, bool strict,
                 for (auto & j : names) {
                     Attr & a(*v.attrs->find(state.symbols.create(j)));
                     auto placeholder(obj.placeholder(j));
-                    printValueAsJSON(state, strict, *a.value, a.pos, placeholder, context);
+                    printValueAsJSON(state, strict, *a.value, a.pos, placeholder, context, copyToStore);
                 }
             } else
-                printValueAsJSON(state, strict, *i->value, i->pos, out, context);
+                printValueAsJSON(state, strict, *i->value, i->pos, out, context, copyToStore);
             break;
         }
 
@@ -65,13 +68,13 @@ void printValueAsJSON(EvalState & state, bool strict,
             auto list(out.list());
             for (auto elem : v.listItems()) {
                 auto placeholder(list.placeholder());
-                printValueAsJSON(state, strict, *elem, pos, placeholder, context);
+                printValueAsJSON(state, strict, *elem, pos, placeholder, context, copyToStore);
             }
             break;
         }
 
         case nExternal:
-            v.external->printValueAsJSON(state, strict, out, context);
+            v.external->printValueAsJSON(state, strict, out, context, copyToStore);
             break;
 
         case nFloat:
@@ -91,14 +94,14 @@ void printValueAsJSON(EvalState & state, bool strict,
 }
 
 void printValueAsJSON(EvalState & state, bool strict,
-    Value & v, const PosIdx pos, std::ostream & str, PathSet & context)
+    Value & v, const PosIdx pos, std::ostream & str, PathSet & context, bool copyToStore)
 {
     JSONPlaceholder out(str);
-    printValueAsJSON(state, strict, v, pos, out, context);
+    printValueAsJSON(state, strict, v, pos, out, context, copyToStore);
 }
 
 void ExternalValueBase::printValueAsJSON(EvalState & state, bool strict,
-    JSONPlaceholder & out, PathSet & context) const
+    JSONPlaceholder & out, PathSet & context, bool copyToStore) const
 {
     state.debugThrowLastTrace(TypeError("cannot convert %1% to JSON", showType()));
 }
diff --git a/src/libexpr/value-to-json.hh b/src/libexpr/value-to-json.hh
index c020a817a..7ddc8a5b1 100644
--- a/src/libexpr/value-to-json.hh
+++ b/src/libexpr/value-to-json.hh
@@ -11,9 +11,9 @@ namespace nix {
 class JSONPlaceholder;
 
 void printValueAsJSON(EvalState & state, bool strict,
-    Value & v, const PosIdx pos, JSONPlaceholder & out, PathSet & context);
+    Value & v, const PosIdx pos, JSONPlaceholder & out, PathSet & context, bool copyToStore = true);
 
 void printValueAsJSON(EvalState & state, bool strict,
-    Value & v, const PosIdx pos, std::ostream & str, PathSet & context);
+    Value & v, const PosIdx pos, std::ostream & str, PathSet & context, bool copyToStore = true);
 
 }
diff --git a/src/libexpr/value.hh b/src/libexpr/value.hh
index 2008df74d..590ba7783 100644
--- a/src/libexpr/value.hh
+++ b/src/libexpr/value.hh
@@ -99,7 +99,7 @@ class ExternalValueBase
 
     /* Print the value as JSON. Defaults to unconvertable, i.e. throws an error */
     virtual void printValueAsJSON(EvalState & state, bool strict,
-        JSONPlaceholder & out, PathSet & context) const;
+        JSONPlaceholder & out, PathSet & context, bool copyToStore = true) const;
 
     /* Print the value as XML. Defaults to unevaluated */
     virtual void printValueAsXML(EvalState & state, bool strict, bool location,
diff --git a/src/nix-instantiate/nix-instantiate.cc b/src/nix-instantiate/nix-instantiate.cc
index d3144e131..6b5ba595d 100644
--- a/src/nix-instantiate/nix-instantiate.cc
+++ b/src/nix-instantiate/nix-instantiate.cc
@@ -52,9 +52,10 @@ void processExpr(EvalState & state, const Strings & attrPaths,
                 state.autoCallFunction(autoArgs, v, vRes);
             if (output == okXML)
                 printValueAsXML(state, strict, location, vRes, std::cout, context, noPos);
-            else if (output == okJSON)
+            else if (output == okJSON) {
                 printValueAsJSON(state, strict, vRes, v.determinePos(noPos), std::cout, context);
-            else {
+                std::cout << std::endl;
+            } else {
                 if (strict) state.forceValueDeep(vRes);
                 vRes.print(state.symbols, std::cout);
                 std::cout << std::endl;
diff --git a/src/nix/eval.cc b/src/nix/eval.cc
index 967dc8519..ddd2790c6 100644
--- a/src/nix/eval.cc
+++ b/src/nix/eval.cc
@@ -116,7 +116,8 @@ struct CmdEval : MixJSON, InstallableCommand
 
         else if (json) {
             JSONPlaceholder jsonOut(std::cout);
-            printValueAsJSON(*state, true, *v, pos, jsonOut, context);
+            printValueAsJSON(*state, true, *v, pos, jsonOut, context, false);
+            std::cout << std::endl;
         }
 
         else {