diff --git a/Makefile.in b/Makefile.in
index 57cde9de75f9eb8536422924e0c32fb454b033aa..115bcd2e3f2cb1e0252d248a6ae6ba5fd9b84b0f 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -198,7 +198,8 @@ am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/ar-lib \
 	$(top_srcdir)/config/missing \
 	$(top_srcdir)/inc/lektor/lktconfig.h.in config/ar-lib \
 	config/compile config/config.guess config/config.sub \
-	config/install-sh config/ltmain.sh config/missing
+	config/depcomp config/install-sh config/ltmain.sh \
+	config/missing
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 distdir = $(PACKAGE)-$(VERSION)
 top_distdir = $(distdir)
diff --git a/configure b/configure
index 47c35a6da120ea877ac243190c34fec5b8dfec92..694436cec5db4b0c8adac0f40371da29267bd74d 100755
--- a/configure
+++ b/configure
@@ -2275,7 +2275,6 @@ as_fn_append ac_header_list " stdargs.h"
 as_fn_append ac_header_list " ctypes.h"
 as_fn_append ac_header_list " regex.h"
 as_fn_append ac_header_list " locale.h"
-as_fn_append ac_header_list " assert.h"
 # Check that the precious variables saved in the cache have kept the same
 # value.
 ac_cache_corrupted=false
@@ -3871,8 +3870,6 @@ done
 
 
 
-
-
 
 
 
diff --git a/configure.ac b/configure.ac
index cb32e83304ef2bb4816f18fb84ad272d725f0b45..42e250a6e7b8949aa1b063e1f23fc74aa1f5957e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -39,7 +39,6 @@ AC_CHECK_HEADERS_ONCE([
     ctypes.h
     regex.h
     locale.h
-    assert.h
 ])
 
 AC_C_INLINE
diff --git a/inc/lektor/common.h b/inc/lektor/common.h
index 669884552f279562a5910dc4f0b9a7fdc98e5588..ad703fbc6cb47e555586cea69998c57361e9335b 100644
--- a/inc/lektor/common.h
+++ b/inc/lektor/common.h
@@ -43,6 +43,18 @@
     err_flag = errno != 0 || endptr == str;                 \
 }
 
+/* Custom defined assert. */
+extern void (*__lkt_assert)(const char *file, int line, const char *func, const char *msg);
+#ifdef assert
+    #undef assert
+#endif
+#ifdef NDEBUG
+    #define assert(ex)
+#else
+    #define assert(ex) (void) ((ex) || (__lkt_assert(__FILE__, __LINE__, __func__, #ex), 0))
+#endif
+
+/* Custom log functions. */
 extern int log_level;
 enum log_level {
     ERROR   = 1,
@@ -50,7 +62,6 @@ enum log_level {
     INFO    = 3,
     DEBUG   = 4,
 };
-
 void __lkt_log(enum log_level, const char *section, const char *func, const char *format, ...);
 #define LOG_INFO( section, ...) __lkt_log(INFO,  section, __func__, __VA_ARGS__)
 #define LOG_WARN( section, ...) __lkt_log(WARN,  section, __func__, __VA_ARGS__)
@@ -63,6 +74,7 @@ void __lkt_log(enum log_level, const char *section, const char *func, const char
 
 #define LKT_ENV_RESTART             "__LKT_RESTART"
 #define LKT_ENV_CURRENT             "__LKT_CURRENT"
+#define LKT_ENV_SET_ASSERT          "__LKT_SET_ASSERT"
 
 #define LKT_LINE_MAX                1024
 #define LKT_MAX_SQLITE_STATEMENT    1024
@@ -177,9 +189,6 @@ void __unused(void *, ...);
 
 long get_mtime(const char *path);
 
-void *safe_malloc(size_t size);
-void *safe_zero_malloc(size_t size);
-
 int is_utf8(const char *string);
 
 /* Same as `be_uint64_t` but for Big-endian doubles. The result is a
@@ -213,8 +222,11 @@ int get_stdin_line(const char *prompt, char *buf, size_t len);
 
 int read_self_exe(char *path, size_t len);
 
-int safe_snprintf(char *dest, const size_t max_len, const char *format, ...);
-
 long long_length(long integer);
 
+/* Safe functions, which preserve the terminal '\0'. */
+void *safe_malloc(size_t size);
+void *safe_zero_malloc(size_t size);
+int safe_snprintf(char *dest, const size_t max_len, const char *format, ...);
+
 #endif /* __LKT_COMMON_H__ */
diff --git a/inc/lektor/lktconfig.h.in b/inc/lektor/lktconfig.h.in
index 833b96d19dd348b08db54231b44b31647d5db6d9..04956b43d8f885283607d1eb96e2fb49026d47b1 100644
--- a/inc/lektor/lktconfig.h.in
+++ b/inc/lektor/lktconfig.h.in
@@ -1,8 +1,5 @@
 /* inc/lektor/lktconfig.h.in.  Generated from configure.ac by autoheader.  */
 
-/* Define to 1 if you have the <assert.h> header file. */
-#undef HAVE_ASSERT_H
-
 /* Define to 1 if you have the <ctypes.h> header file. */
 #undef HAVE_CTYPES_H
 
diff --git a/src/base/common.c b/src/base/common.c
index e0f662560e854454c9ea248930b0a15e816ea152..7d76ad345b8bcaff011d6388eb564475c1bf98ef 100644
--- a/src/base/common.c
+++ b/src/base/common.c
@@ -8,6 +8,34 @@
 #include <stdarg.h>
 #include <sys/stat.h>
 
+/* Assert function */
+
+static void
+__no_assert(const char __attribute__((unused)) *file, int __attribute__((unused)) line,
+            const char __attribute__((unused)) *func, const char __attribute__((unused)) *msg)
+{
+}
+
+static void
+__yes_assert(const char *file, int line, const char *func, const char *msg)
+{
+    fprintf(stderr, " F [ASSERT] %s:%s:%d: %s\n", file, func, line, msg);
+}
+
+void (*__lkt_assert)(const char *file, int line, const char *func, const char *msg) = NULL;
+
+__attribute__((constructor)) static void
+__set_assert(void)
+{
+    const char *no_assert = getenv(LKT_ENV_SET_ASSERT);
+    if (NULL == no_assert || strlen(no_assert) == 0)
+        __lkt_assert = __yes_assert;
+    else
+        __lkt_assert = __no_assert;
+}
+
+/* Log functions */
+
 int log_level = 0; /* None by default */
 
 void
@@ -26,6 +54,8 @@ __lkt_log(enum log_level level, const char *section, const char *func, const cha
     }
 }
 
+/* Not implemented */
+
 void
 __not_implemented(const char *func, char *file, int line)
 {
diff --git a/src/main/lkt.c b/src/main/lkt.c
index b5d166511f636bdd1d4906bdd70580a0290791a1..042d346729fd039594a4a981a13398d0fc70082a 100644
--- a/src/main/lkt.c
+++ b/src/main/lkt.c
@@ -21,7 +21,6 @@
 #include <signal.h>
 #include <locale.h>
 #include <stdnoreturn.h>
-#include <assert.h>
 #include <stdbool.h>
 #include <stdarg.h>
 #include <limits.h>
diff --git a/src/main/server.c b/src/main/server.c
index 02583051665001c324dd78eba77cd5e2a6848070..fb1c4cba36eb85672f9372d02559d9d71694f429 100644
--- a/src/main/server.c
+++ b/src/main/server.c
@@ -9,7 +9,6 @@
 #include <lektor/database.h>
 #include <lektor/commands.h>
 
-#include <assert.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/src/module/module_repo.c b/src/module/module_repo.c
index 2e08eedd2ced0ba27c96af79294d7d3b4930487d..fc93c722f26819397560f8a2d409a2690e36d4d3 100644
--- a/src/module/module_repo.c
+++ b/src/module/module_repo.c
@@ -227,7 +227,7 @@ __handle_got_json(volatile sqlite3 *db, struct module_repo_internal *repo,
                   struct json_object *json)
 {
     size_t i, ignored_count = 0, update_count = 0,
-           len = json_object_array_length(json);
+              len = json_object_array_length(json);
     struct json_object *kara_json;
     struct kara kara;
     long filestamp = 0, timestamp = 0, download_id;
diff --git a/src/module/module_sdl2.c b/src/module/module_sdl2.c
index 874756c32aedc89fd6f965f04c50366ec578a2bb..4de7b6df06d3d9bf6d84bd479ace1cbc1234ecff 100644
--- a/src/module/module_sdl2.c
+++ b/src/module/module_sdl2.c
@@ -11,7 +11,6 @@
 
 #include <sqlite3.h>
 #include <sched.h>
-#include <assert.h>
 #include <string.h>
 #include <unistd.h>
 #include <stdlib.h>
diff --git a/src/module/worker.c b/src/module/worker.c
index 08748ec7406f04de243c4aa84d260e484bb87d05..7b23b70cb70dabaadbe2c1c3692b1712ac05a246 100644
--- a/src/module/worker.c
+++ b/src/module/worker.c
@@ -5,7 +5,6 @@
 
 #include <stdio.h>
 #include <pthread.h>
-#include <assert.h>
 #include <sys/sysinfo.h>
 #include <sched.h>
 #include <errno.h>
diff --git a/src/net/listen.c b/src/net/listen.c
index f5fc4493e6577c1b0f65a95e88245483adf88dbb..380cebe9dc8eab8262ada15a31a1b6cbd6ee0dbe 100644
--- a/src/net/listen.c
+++ b/src/net/listen.c
@@ -11,7 +11,6 @@
 
 #include <strings.h>
 #include <sched.h>
-#include <assert.h>
 #include <arpa/inet.h>
 #include <errno.h>
 #include <fcntl.h>