diff --git a/CHANGELOG.md b/CHANGELOG.md
index cc992beb..b8809183 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,6 +19,7 @@
 - Change `Float.parseFloat` signature. Now accepts only string. https://github.com/rescript-association/rescript-core/pull/54
 - Add `getExn`, `getUnsafe`, `getWithDefault`, `map`, `mapWithDefault` and `flatMap` to `Nullable`. https://github.com/rescript-association/rescript-core/pull/67
 - Add `getExn`, `getUnsafe`, `getWithDefault`, `map`, `mapWithDefault` and `flatMap` to `Null`. https://github.com/rescript-association/rescript-core/pull/73
+- Add `panic`/`Error.panic` and use that where appropriate: https://github.com/rescript-association/rescript-core/pull/72
 
 ### Documentation
 
diff --git a/package.json b/package.json
index d23f0f91..f4a3fb7b 100644
--- a/package.json
+++ b/package.json
@@ -5,11 +5,9 @@
     "clean": "rescript clean",
     "build": "rescript",
     "watch": "rescript build -w",
-    "test": "node test/PromiseTest.mjs && node test/TempTests.mjs"
+    "test": "node test/TestSuite.mjs && node test/TempTests.mjs"
   },
-  "keywords": [
-    "rescript"
-  ],
+  "keywords": ["rescript"],
   "homepage": "https://github.com/rescript-association/rescript-core",
   "author": "ReScript Team",
   "license": "MIT",
diff --git a/src/Core__Error.mjs b/src/Core__Error.mjs
index b9e0a7a0..e5334cf8 100644
--- a/src/Core__Error.mjs
+++ b/src/Core__Error.mjs
@@ -13,6 +13,10 @@ var $$TypeError = {};
 
 var $$URIError = {};
 
+function panic(msg) {
+  throw new Error("Panic! " + msg);
+}
+
 export {
   $$EvalError ,
   $$RangeError ,
@@ -20,5 +24,6 @@ export {
   $$SyntaxError ,
   $$TypeError ,
   $$URIError ,
+  panic ,
 }
 /* No side effect */
diff --git a/src/Core__Error.res b/src/Core__Error.res
index 69e05994..788e0bdb 100644
--- a/src/Core__Error.res
+++ b/src/Core__Error.res
@@ -35,3 +35,5 @@ module URIError = {
 }
 
 external raise: t => 'a = "%raise"
+
+let panic = msg => make(j`Panic! $msg`)->raise
diff --git a/src/Core__Error.resi b/src/Core__Error.resi
index 563c6fc2..76c12c0c 100644
--- a/src/Core__Error.resi
+++ b/src/Core__Error.resi
@@ -155,3 +155,17 @@ if 5 > 10 {
 ```
 */
 external raise: t => 'a = "%raise"
+
+/**
+Raises a panic exception with the given message.
+
+A panic exception is a native JavaScript exception that is not intended to be caught and
+handled. Compared to a ReScript exception this will give a better stack trace and
+debugging experience.
+
+## Examples
+```rescript
+Error.panic("Uh oh. This was unexpected!")
+```
+*/
+let panic: string => 'a
diff --git a/src/Core__List.mjs b/src/Core__List.mjs
index 8da20a23..b9844598 100644
--- a/src/Core__List.mjs
+++ b/src/Core__List.mjs
@@ -4,6 +4,7 @@ import * as Curry from "rescript/lib/es6/curry.js";
 import * as Belt_Array from "rescript/lib/es6/belt_Array.js";
 import * as Caml_option from "rescript/lib/es6/caml_option.js";
 import * as Core__Array from "./Core__Array.mjs";
+import * as Core__Error from "./Core__Error.mjs";
 
 function head(x) {
   if (x) {
@@ -15,11 +16,9 @@ function head(x) {
 function headExn(x) {
   if (x) {
     return x.hd;
+  } else {
+    return Core__Error.panic("List.headExn: list is empty");
   }
-  throw {
-        RE_EXN_ID: "Not_found",
-        Error: new Error()
-      };
 }
 
 function tail(x) {
@@ -32,11 +31,9 @@ function tail(x) {
 function tailExn(x) {
   if (x) {
     return x.tl;
+  } else {
+    return Core__Error.panic("List.tailExn: list is empty");
   }
-  throw {
-        RE_EXN_ID: "Not_found",
-        Error: new Error()
-      };
 }
 
 function add(xs, x) {
@@ -70,29 +67,24 @@ function get(x, n) {
 
 function getExn(x, n) {
   if (n < 0) {
-    throw {
-          RE_EXN_ID: "Not_found",
-          Error: new Error()
-        };
-  }
-  var _x = x;
-  var _n = n;
-  while(true) {
-    var n$1 = _n;
-    var x$1 = _x;
-    if (x$1) {
+    return Core__Error.panic("List.getExn: n < 0");
+  } else {
+    var _x = x;
+    var _n = n;
+    while(true) {
+      var n$1 = _n;
+      var x$1 = _x;
+      if (!x$1) {
+        return Core__Error.panic("List.nthAuxAssert: list is empty");
+      }
       if (n$1 === 0) {
         return x$1.hd;
       }
       _n = n$1 - 1 | 0;
       _x = x$1.tl;
       continue ;
-    }
-    throw {
-          RE_EXN_ID: "Not_found",
-          Error: new Error()
-        };
-  };
+    };
+  }
 }
 
 function partitionAux(p, _cell, _precX, _precY) {
diff --git a/src/Core__List.res b/src/Core__List.res
index 27c248e7..7aa88386 100644
--- a/src/Core__List.res
+++ b/src/Core__List.res
@@ -94,7 +94,7 @@ let head = x =>
 
 let headExn = x =>
   switch x {
-  | list{} => raise(Not_found)
+  | list{} => Core__Error.panic("List.headExn: list is empty")
   | list{x, ..._} => x
   }
 
@@ -106,7 +106,7 @@ let tail = x =>
 
 let tailExn = x =>
   switch x {
-  | list{} => raise(Not_found)
+  | list{} => Core__Error.panic("List.tailExn: list is empty")
   | list{_, ...t} => t
   }
 
@@ -132,7 +132,7 @@ let rec nthAuxAssert = (x, n) =>
     } else {
       nthAuxAssert(t, n - 1)
     }
-  | _ => raise(Not_found)
+  | list{} => Core__Error.panic("List.nthAuxAssert: list is empty")
   }
 
 let get = (x, n) =>
@@ -144,7 +144,7 @@ let get = (x, n) =>
 
 let getExn = (x, n) =>
   if n < 0 {
-    raise(Not_found)
+    Core__Error.panic("List.getExn: n < 0")
   } else {
     nthAuxAssert(x, n)
   }
diff --git a/src/Core__List.resi b/src/Core__List.resi
index 189083af..b97b54f5 100644
--- a/src/Core__List.resi
+++ b/src/Core__List.resi
@@ -82,7 +82,7 @@ List.headExn(list{}) // Raises an Error
 
 ## Exceptions
 
-- Raises an Error if list is empty.
+- Panics if list is empty.
 
 */
 let headExn: t<'a> => 'a
@@ -114,7 +114,7 @@ List.tailExn(list{}) // Raises an Error
 
 ## Exceptions
 
-- Raises an Error if list is empty.
+- Panics if list is empty.
 */
 let tailExn: t<'a> => t<'a>
 
@@ -162,7 +162,7 @@ abc->List.getExn(4) // Raises an Error
 
 ## Exceptions
 
-- Raises an Error if `index` is larger than the length of list.
+- Panics if `index` is less than 0 or larger than the length of list.
 */
 let getExn: (t<'a>, int) => 'a
 
diff --git a/src/Core__Option.mjs b/src/Core__Option.mjs
index 29ad429b..052265a2 100644
--- a/src/Core__Option.mjs
+++ b/src/Core__Option.mjs
@@ -2,6 +2,7 @@
 
 import * as Curry from "rescript/lib/es6/curry.js";
 import * as Caml_option from "rescript/lib/es6/caml_option.js";
+import * as Core__Error from "./Core__Error.mjs";
 
 function filter(opt, p) {
   var p$1 = Curry.__1(p);
@@ -22,11 +23,9 @@ function forEach(opt, f) {
 function getExn(x) {
   if (x !== undefined) {
     return Caml_option.valFromOption(x);
+  } else {
+    return Core__Error.panic("List.headExn: option is None");
   }
-  throw {
-        RE_EXN_ID: "Not_found",
-        Error: new Error()
-      };
 }
 
 function mapWithDefault(opt, $$default, f) {
diff --git a/src/Core__Option.res b/src/Core__Option.res
index 9b688647..19802440 100644
--- a/src/Core__Option.res
+++ b/src/Core__Option.res
@@ -41,7 +41,7 @@ let forEach = (opt, f) => forEachU(opt, (. x) => f(x))
 let getExn = x =>
   switch x {
   | Some(x) => x
-  | None => raise(Not_found)
+  | None => Core__Error.panic("List.headExn: option is None")
   }
 
 external getUnsafe: option<'a> => 'a = "%identity"
diff --git a/src/Core__Option.resi b/src/Core__Option.resi
index fb3c8a46..a2d348ed 100644
--- a/src/Core__Option.resi
+++ b/src/Core__Option.resi
@@ -75,7 +75,7 @@ Option.getExn(None) /* Raises an Error */
 
 ## Exceptions
 
-- Raises an error if `opt` is `None`
+- Panics if `opt` is `None`
 */
 let getExn: option<'a> => 'a
 
diff --git a/src/Core__Result.mjs b/src/Core__Result.mjs
index 832ab968..e8c8aba0 100644
--- a/src/Core__Result.mjs
+++ b/src/Core__Result.mjs
@@ -1,15 +1,14 @@
 // Generated by ReScript, PLEASE EDIT WITH CARE
 
 import * as Curry from "rescript/lib/es6/curry.js";
+import * as Core__Error from "./Core__Error.mjs";
 
 function getExn(x) {
   if (x.TAG === /* Ok */0) {
     return x._0;
+  } else {
+    return Core__Error.panic("Result.getExn: result is Error");
   }
-  throw {
-        RE_EXN_ID: "Not_found",
-        Error: new Error()
-      };
 }
 
 function mapWithDefault(opt, $$default, f) {
diff --git a/src/Core__Result.res b/src/Core__Result.res
index 51032a64..56f3d8fb 100644
--- a/src/Core__Result.res
+++ b/src/Core__Result.res
@@ -27,7 +27,7 @@ type t<'a, 'b> = result<'a, 'b> = Ok('a) | Error('b)
 let getExn = x =>
   switch x {
   | Ok(x) => x
-  | Error(_) => raise(Not_found)
+  | Error(_) => Core__Error.panic("Result.getExn: result is Error")
   }
 
 let mapWithDefaultU = (opt, default, f) =>
diff --git a/src/Core__Result.resi b/src/Core__Result.resi
index d1e6636d..6eeebdd3 100644
--- a/src/Core__Result.resi
+++ b/src/Core__Result.resi
@@ -55,6 +55,10 @@ type t<'a, 'b> = result<'a, 'b> = Ok('a) | Error('b)
 
   Result.getExn(Result.Error("Invalid data")) /* raises exception */
   ```
+
+## Exceptions
+
+- Panics if `res` is `Error(_)`
 */
 let getExn: t<'a, 'b> => 'a
 
diff --git a/src/RescriptCore.mjs b/src/RescriptCore.mjs
index 7706a777..334f6e2d 100644
--- a/src/RescriptCore.mjs
+++ b/src/RescriptCore.mjs
@@ -1,5 +1,6 @@
 // Generated by ReScript, PLEASE EDIT WITH CARE
 
+import * as Core__Error from "./Core__Error.mjs";
 
 var $$Array;
 
@@ -93,6 +94,8 @@ var List;
 
 var Result;
 
+var panic = Core__Error.panic;
+
 export {
   $$Array ,
   Console ,
@@ -140,5 +143,6 @@ export {
   $$Option ,
   List ,
   Result ,
+  panic ,
 }
 /* No side effect */
diff --git a/src/RescriptCore.res b/src/RescriptCore.res
index 7cd77db2..d76bcde0 100644
--- a/src/RescriptCore.res
+++ b/src/RescriptCore.res
@@ -65,3 +65,5 @@ type null<+'a> = Js.null<'a>
 type undefined<+'a> = Js.undefined<'a>
 
 type nullable<+'a> = Js.nullable<'a>
+
+let panic = Core__Error.panic
diff --git a/test/ErrorTests.mjs b/test/ErrorTests.mjs
new file mode 100644
index 00000000..a9af7afb
--- /dev/null
+++ b/test/ErrorTests.mjs
@@ -0,0 +1,39 @@
+// Generated by ReScript, PLEASE EDIT WITH CARE
+
+import * as Test from "./Test.mjs";
+import * as Js_exn from "rescript/lib/es6/js_exn.js";
+import * as RescriptCore from "../src/RescriptCore.mjs";
+import * as Caml_js_exceptions from "rescript/lib/es6/caml_js_exceptions.js";
+
+function panicTest(param) {
+  var caught;
+  try {
+    caught = RescriptCore.panic("uh oh");
+  }
+  catch (raw_err){
+    var err = Caml_js_exceptions.internalToOCamlException(raw_err);
+    if (err.RE_EXN_ID === Js_exn.$$Error) {
+      caught = err._1.message;
+    } else {
+      throw err;
+    }
+  }
+  Test.run([
+        [
+          "ErrorTests.res",
+          8,
+          22,
+          43
+        ],
+        "Should resolve test"
+      ], caught, (function (prim0, prim1) {
+          return prim0 === prim1;
+        }), "Panic! uh oh");
+}
+
+panicTest(undefined);
+
+export {
+  panicTest ,
+}
+/*  Not a pure module */
diff --git a/test/ErrorTests.res b/test/ErrorTests.res
new file mode 100644
index 00000000..07dcc078
--- /dev/null
+++ b/test/ErrorTests.res
@@ -0,0 +1,11 @@
+open RescriptCore
+
+let panicTest = () => {
+  let caught = try panic("uh oh") catch {
+  | Exn.Error(err) => Error.message(err)
+  }
+
+  Test.run(__POS_OF__("Should resolve test"), caught, \"==", Some("Panic! uh oh"))
+}
+
+panicTest()
diff --git a/test/TestSuite.mjs b/test/TestSuite.mjs
new file mode 100644
index 00000000..bde8356a
--- /dev/null
+++ b/test/TestSuite.mjs
@@ -0,0 +1,35 @@
+// Generated by ReScript, PLEASE EDIT WITH CARE
+
+import * as ErrorTests from "./ErrorTests.mjs";
+import * as PromiseTest from "./PromiseTest.mjs";
+
+var TestError = PromiseTest.TestError;
+
+var fail = PromiseTest.fail;
+
+var equal = PromiseTest.equal;
+
+var Creation = PromiseTest.Creation;
+
+var ThenChaining = PromiseTest.ThenChaining;
+
+var Rejection = PromiseTest.Rejection;
+
+var Catching = PromiseTest.Catching;
+
+var Concurrently = PromiseTest.Concurrently;
+
+var panicTest = ErrorTests.panicTest;
+
+export {
+  TestError ,
+  fail ,
+  equal ,
+  Creation ,
+  ThenChaining ,
+  Rejection ,
+  Catching ,
+  Concurrently ,
+  panicTest ,
+}
+/* ErrorTests Not a pure module */
diff --git a/test/TestSuite.res b/test/TestSuite.res
new file mode 100644
index 00000000..c2ae6367
--- /dev/null
+++ b/test/TestSuite.res
@@ -0,0 +1,2 @@
+include PromiseTest
+include ErrorTests