diff --git a/configure.ac b/configure.ac
index 5c24f68851c87580723d6494be6b4a49f95c03d6..93fc7ef239b7eb0056f8903aa37332590350e7a6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -37,7 +37,6 @@ AM_CHECK_LIBUV
 AC_CHECK_HEADERS([stdlib.h],,, [AC_INCLUDES_DEFAULT])
 
 # Search libraries
-AC_SEARCH_LIBS([knot_rrset_clear], [knot])
 AC_SEARCH_LIBS([mdb_env_open], [lmdb])
 
 # Config files
diff --git a/daemon/layer/query.c b/daemon/layer/query.c
index 64f570a0a0caac7552cfcb8bf197226a9b9eb857..f97bb44712bb7bac67441fd010bfe482a2a4ef17 100644
--- a/daemon/layer/query.c
+++ b/daemon/layer/query.c
@@ -18,7 +18,7 @@ limitations under the License.
 
 static int reset(knot_layer_t *ctx)
 {
-	return NS_PROC_MORE;
+	return KNOT_NS_PROC_MORE;
 }
 
 static int begin(knot_layer_t *ctx, void *module_param)
@@ -34,12 +34,12 @@ static int input_query(knot_layer_t *ctx, knot_pkt_t *pkt)
 
 	/* Check if at least header is parsed. */
 	if (pkt->parsed < pkt->size) {
-		return NS_PROC_FAIL;
+		return KNOT_NS_PROC_FAIL;
 	}
 
 	/* Accept only queries. */
 	if (knot_wire_get_qr(pkt->wire)) {
-		return NS_PROC_NOOP; /* Ignore. */
+		return KNOT_NS_PROC_NOOP; /* Ignore. */
 	}
 
 	/* Prepare for query processing. */
@@ -53,9 +53,9 @@ static int input_query(knot_layer_t *ctx, knot_pkt_t *pkt)
 	knot_wire_set_id(answer->wire, knot_wire_get_id(pkt->wire));
 
 	if (ret != 0) {
-		return NS_PROC_FAIL;
+		return KNOT_NS_PROC_FAIL;
 	} else {
-		return NS_PROC_DONE;
+		return KNOT_NS_PROC_DONE;
 	}
 }
 
diff --git a/daemon/worker.c b/daemon/worker.c
index 9a01ddeebaf52d18032ede269bbf76aaf426eef2..4c752882e56e501f7ff9620cd0bcc158a7f614d3 100644
--- a/daemon/worker.c
+++ b/daemon/worker.c
@@ -1,7 +1,7 @@
 #include <uv.h>
 
 #include <libknot/packet/pkt.h>
-#include <libknot/packet/net.h>
+#include <common/net.h>
 
 #include "daemon/worker.h"
 #include "daemon/layer/query.h"
@@ -52,7 +52,7 @@ static void worker_recv(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf,
 	knot_pkt_t *query = knot_pkt_new((uint8_t *)buf->base, nread, ctx->pool);
 	knot_pkt_parse(query, 0);
 	int state = knot_layer_in(&proc, query);
-	if (state & (NS_PROC_DONE|NS_PROC_FAIL)) {
+	if (state & (KNOT_NS_PROC_DONE|KNOT_NS_PROC_FAIL)) {
 		worker_send(handle, result.ans, addr);
 	}
 
diff --git a/daemon/worker.h b/daemon/worker.h
index 7312a6eda838a20d0d36b55badb156856fbfdf46..f4efd10f8206f70e86c4527e3f8b7554b68e786b 100644
--- a/daemon/worker.h
+++ b/daemon/worker.h
@@ -17,7 +17,7 @@ limitations under the License.
 
 #include <uv.h>
 
-#include <libknot/mempattern.h>
+#include <common/mempattern.h>
 #include "lib/resolve.h"
 
 struct worker_ctx {
diff --git a/lib/cache.c b/lib/cache.c
index 09eeb27ad18dc041ebe71d78207402cde32da835..dcd345d19863e7c34f88310ec45a0beb65bc8f3b 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -2,7 +2,7 @@
 #include <time.h>
 
 #include <lmdb.h>
-#include <libknot/mempattern.h>
+#include <common/mempattern.h>
 #include <libknot/descriptor.h>
 
 #include "lib/cache.h"
@@ -133,7 +133,7 @@ static int pack_entry(MDB_cursor *cur, const knot_dname_t *name, uint16_t type,
 	MDB_val key = pack_key(name);
 	MDB_val data = { datalen, buf };
 
-	return mdb_cursor_put(cur, &key, &data, MDB_APPENDDUP);
+	return mdb_cursor_put(cur, &key, &data, 0);
 }
 
 static int pack_list(MDB_cursor *cur, const knot_rrset_t *rr)
@@ -151,9 +151,9 @@ static int pack_list(MDB_cursor *cur, const knot_rrset_t *rr)
 	}
 
 #ifndef NDEBUG
-	char *owner = knot_dname_to_str(rr->owner);
+	char owner[KNOT_DNAME_MAXLEN] = { '\0' };
+	knot_dname_to_str(owner, rr->owner, sizeof(owner) - 1);
 	DEBUG_MSG("STORE RR '%s' TYPE %u, %u RDATA => %s\n", owner, rr->type, rr->rrs.rr_count, mdb_strerror(ret));
-	free(owner);
 #endif
 
 	return ret;
@@ -196,9 +196,9 @@ static int unpack_list(MDB_cursor *cur, knot_rrset_t *rr, mm_ctx_t *mm)
 	}
 
 #ifndef NDEBUG
-	char *owner = knot_dname_to_str(rr->owner);
+	char owner[KNOT_DNAME_MAXLEN] = { '\0' };
+	knot_dname_to_str(owner, rr->owner, sizeof(owner) - 1);
 	DEBUG_MSG("LOAD RR '%s' TYPE %u => %u RECORDS\n", owner, rr->type, rr->rrs.rr_count);
-	free(owner);
 #endif
 
 	/* Update TTL for all records. */
@@ -236,6 +236,8 @@ void kr_cache_close(struct kr_cache *cache)
 
 struct kr_txn *kr_cache_txn_begin(struct kr_cache *cache, struct kr_txn *parent, unsigned flags, mm_ctx_t *mm)
 {
+	assert(cache);
+	
 	struct kr_txn *txn = mm_alloc(mm, sizeof(struct kr_txn));
 	if (txn == NULL) {
 		return NULL;
@@ -342,9 +344,9 @@ int kr_cache_remove(struct kr_txn *txn, const knot_rrset_t *rr)
 		    knot_rdataset_member(&rr->rrs, PACKED_RDATA(data.mv_data), false)) {
 			mdb_cursor_del(cursor, 0);
 #ifndef NDEBUG
-			char *owner = knot_dname_to_str(rr->owner);
+			char owner[KNOT_DNAME_MAXLEN] = { '\0' };
+			knot_dname_to_str(owner, rr->owner, sizeof(owner) - 1);
 			DEBUG_MSG("DEL RR '%s' TYPE %u (%p)\n", owner, rr->type, PACKED_RDATA(data.mv_data));
-			free(owner);
 #endif
 		}
 	}
diff --git a/lib/context.h b/lib/context.h
index 1f55536fc5ac4a4648115bacf26e998da1585f55..1e8960cbd81324f6cc5337cc6534d31ab1d13fdd 100644
--- a/lib/context.h
+++ b/lib/context.h
@@ -16,7 +16,7 @@ limitations under the License.
 #pragma once
 
 #include <stdint.h>
-#include <libknot/mempattern.h>
+#include <common/mempattern.h>
 #include <common/sockaddr.h>
 
 #include "lib/delegpt.h"
diff --git a/lib/layer/iterate.c b/lib/layer/iterate.c
index 4dba091fe5d07461dc5371c79e5e35ba7b0755c1..9477698922bbc215605e6483f4863b0313c281e1 100644
--- a/lib/layer/iterate.c
+++ b/lib/layer/iterate.c
@@ -96,7 +96,7 @@ static int resolve_nonauth(knot_pkt_t *pkt, struct kr_layer_param *param)
 		}
 	}
 
-	return NS_PROC_DONE;
+	return KNOT_NS_PROC_DONE;
 }
 
 static void follow_cname_chain(const knot_dname_t **cname, const knot_rrset_t *rr,
@@ -127,7 +127,7 @@ static int update_query(struct kr_query *qry, struct kr_result *result, const kn
 	}
 
 	/* Write copied RR to the result packet. */
-	int ret = knot_pkt_put(ans, COMPR_HINT_NONE, rr_copy, KNOT_PF_FREE);
+	int ret = knot_pkt_put(ans, KNOT_COMPR_HINT_NONE, rr_copy, KNOT_PF_FREE);
 	if (ret != 0) {
 		knot_rrset_free(&rr_copy, &ans->mm);
 		knot_wire_set_tc(ans->wire);
@@ -192,7 +192,7 @@ static int resolve_auth(knot_pkt_t *pkt, struct kr_layer_param *param)
 	knot_pkt_t *ans = result->ans;
 	struct kr_query *cur = kr_rplan_next(&resolve->rplan);
 	if (cur == NULL) {
-		return NS_PROC_FAIL;
+		return KNOT_NS_PROC_FAIL;
 	}
 
 	/* Store flags. */
@@ -205,7 +205,7 @@ static int resolve_auth(knot_pkt_t *pkt, struct kr_layer_param *param)
 		/* RR callbacks per query type. */
 		int ret = update_result(cur, result, &an->rr[i]);
 		if (ret != 0) {
-			return NS_PROC_FAIL;
+			return KNOT_NS_PROC_FAIL;
 		}
 
 		/* Update cache. */
@@ -222,20 +222,20 @@ static int resolve_auth(knot_pkt_t *pkt, struct kr_layer_param *param)
 		struct kr_query *next = kr_rplan_push(&resolve->rplan, cname,
 		                                      cur->sclass, cur->stype);
 		if (next == NULL) {
-			return NS_PROC_FAIL;
+			return KNOT_NS_PROC_FAIL;
 		}
 	}
 
 	/* Resolved current SNAME. */
 	resolve->resolved_qry = cur;
 
-	return NS_PROC_DONE;
+	return KNOT_NS_PROC_DONE;
 }
 
 /*! \brief Error handling, RFC1034 5.3.3, 4d. */
 static int resolve_error(knot_pkt_t *pkt, struct kr_layer_param *param)
 {
-	return NS_PROC_FAIL;
+	return KNOT_NS_PROC_FAIL;
 }
 
 /*! \brief Answer is paired to query. */
@@ -253,8 +253,8 @@ static bool is_answer_to_query(const knot_pkt_t *answer, struct kr_context *reso
 }
 
 /* State-less single resolution iteration step, not needed. */
-static int reset(knot_layer_t *ctx)  { return NS_PROC_FULL; }
-static int finish(knot_layer_t *ctx) { return NS_PROC_NOOP; }
+static int reset(knot_layer_t *ctx)  { return KNOT_NS_PROC_FULL; }
+static int finish(knot_layer_t *ctx) { return KNOT_NS_PROC_NOOP; }
 
 /* Set resolution context and parameters. */
 static int begin(knot_layer_t *ctx, void *module_param)
@@ -287,7 +287,7 @@ static int prepare_query(knot_layer_t *ctx, knot_pkt_t *pkt)
 		knot_wire_set_rcode(result->ans->wire, KNOT_RCODE_NOERROR);
 		resolve->resolved_qry = next;
 		kr_context_txn_release(txn);
-		return NS_PROC_DONE;
+		return KNOT_NS_PROC_DONE;
 	}
 	knot_rdataset_clear(&cached_reply.rrs, resolve->pool);
 	kr_context_txn_release(txn);
@@ -296,13 +296,13 @@ static int prepare_query(knot_layer_t *ctx, knot_pkt_t *pkt)
 
 	int ret = knot_pkt_put_question(pkt, next->sname, next->sclass, next->stype);
 	if (ret != KNOT_EOK) {
-		return NS_PROC_FAIL;
+		return KNOT_NS_PROC_FAIL;
 	}
 
 	knot_wire_set_id(pkt->wire, knot_random_uint16_t());
 
 	/* Query complete, expect answer. */
-	return NS_PROC_MORE;
+	return KNOT_NS_PROC_MORE;
 }
 
 /*! \brief Resolve input query or continue resolution with followups.
diff --git a/lib/layer/stats.c b/lib/layer/stats.c
index 4b66c0f21a66c964cecb4018b677933bfc72a93b..e696f7641e534eb98064228a12427a48acdc8603 100644
--- a/lib/layer/stats.c
+++ b/lib/layer/stats.c
@@ -70,10 +70,9 @@ static int finish(knot_layer_t *ctx)
 	struct kr_result *result = param->result;
 
 #ifndef NDEBUG
-	char *qnamestr = knot_dname_to_str(knot_pkt_qname(result->ans));
+	char qnamestr[KNOT_DNAME_MAXLEN] = { '\0' };
+	knot_dname_to_str(qnamestr, knot_pkt_qname(result->ans), sizeof(qnamestr) - 1);
 	DEBUG_MSG("resolution of %s\n", qnamestr);
-	free(qnamestr);
-
 	DEBUG_MSG("rcode: %d (%u RRs)\n", knot_wire_get_rcode(result->ans->wire), result->ans->rrset_count);
 	DEBUG_MSG("queries: %u\n", result->nr_queries);
 	DEBUG_MSG("total time: %u msecs\n", result->total_rtt);
@@ -114,15 +113,18 @@ static int answer(knot_layer_t *ctx, knot_pkt_t *pkt)
 	}
 
 #ifndef NDEBUG
-	char *ns_name = knot_dname_to_str(ns->name);
+	char ns_name[KNOT_DNAME_MAXLEN] = { '\0' };
+	knot_dname_to_str(ns_name, ns->name, sizeof(ns_name) - 1);
 	char pad[16];
 	memset(pad, '-', sizeof(pad));
-	pad[MIN(sizeof(pad) - 1, list_size(&resolve->rplan.q) * 2)] = '\0';
+	int pad_len = list_size(&resolve->rplan.q) * 2;
+	if (pad_len > sizeof(pad) - 1) {
+		pad_len = sizeof(pad) - 1;
+	}
 	DEBUG_MSG("#%s %s ... RC=%d, AA=%d, RTT: %.02f msecs\n",
 	          pad, ns_name, knot_wire_get_rcode(pkt->wire),
 	          knot_wire_get_aa(pkt->wire) != 0,
 	          rtt);
-	free(ns_name);
 #endif
 
 	return ctx->state;
diff --git a/lib/resolve.c b/lib/resolve.c
index 9fc4362e58cd415cef9551f84fea91dfd8bfa346..d70716e77adce0c68612c0a086c6cf53833ad20e 100644
--- a/lib/resolve.c
+++ b/lib/resolve.c
@@ -37,7 +37,7 @@ static void iterate(struct knot_requestor *requestor, struct kr_context* ctx)
 	/* Find closest delegation point. */
 	list_t *dp = kr_delegmap_find(&ctx->dp_map, next->sname);
 	if (dp == NULL) {
-		ctx->state = NS_PROC_FAIL;
+		ctx->state = KNOT_NS_PROC_FAIL;
 		return;
 	}
 
@@ -46,7 +46,7 @@ static void iterate(struct knot_requestor *requestor, struct kr_context* ctx)
 
 		/* Dependency loop or inaccessible resolvers, give up. */
 		if (ns->flags & DP_PENDING) {
-			ctx->state = NS_PROC_FAIL;
+			ctx->state = KNOT_NS_PROC_FAIL;
 			return;
 		}
 
@@ -79,9 +79,9 @@ static void iterate(struct knot_requestor *requestor, struct kr_context* ctx)
 
 	/* Continue resolution if has more queries planned. */
 	if (kr_rplan_next(&ctx->rplan) == NULL) {
-		ctx->state = NS_PROC_DONE;
+		ctx->state = KNOT_NS_PROC_DONE;
 	} else {
-		ctx->state = NS_PROC_MORE;
+		ctx->state = KNOT_NS_PROC_MORE;
 	}
 }
 
@@ -93,7 +93,7 @@ int kr_resolve(struct kr_context* ctx, struct kr_result* result,
 	}
 
 	/* Initialize context. */
-	ctx->state = NS_PROC_MORE;
+	ctx->state = KNOT_NS_PROC_MORE;
 	kr_rplan_push(&ctx->rplan, qname, qclass, qtype);
 	kr_result_init(ctx, result);
 
@@ -107,7 +107,7 @@ int kr_resolve(struct kr_context* ctx, struct kr_result* result,
 	knot_requestor_overlay(&requestor, LAYER_STATIC, &param);
 	knot_requestor_overlay(&requestor, LAYER_ITERATE, &param);
 	knot_requestor_overlay(&requestor, LAYER_STATS, &param);
-	while(ctx->state & (NS_PROC_MORE|NS_PROC_FULL)) {
+	while(ctx->state & (KNOT_NS_PROC_MORE|KNOT_NS_PROC_FULL)) {
 		iterate(&requestor, ctx);
 	}
 
diff --git a/m4/libuv.m4 b/m4/libuv.m4
index 04054f392e770116b3a3371e8fb4dccf164f5b31..ab41a702a75292c695656c5519ffab23d1ffdc70 100644
--- a/m4/libuv.m4
+++ b/m4/libuv.m4
@@ -1,19 +1,7 @@
 dnl A macro to check presence of libuv on the system
 AC_DEFUN([AM_CHECK_LIBUV],
 [
-    PKG_CHECK_EXISTS(libuv,
-        [AC_CHECK_HEADERS([uv.h],
-            [], dnl We are only intrested in action-if-not-found
-            [AC_MSG_WARN([Header file uv.h is required.])
-             libuv_required_headers="no"
-            ]
-        )
-        AS_IF([test x"$libuv_required_headers" != x"no"],
-              [PKG_CHECK_MODULES([libuv], [libuv], [have_libuv="yes"])]
-        )],
-        dnl PKG_CHECK_EXISTS ACTION-IF-NOT-FOUND
-        [AC_MSG_WARN([No libuv library found, libuv tests will not be built])]
-    )
-    AM_CONDITIONAL([HAVE_LIBUV], [test x$have_libuv = xyes])
+	AC_CHECK_HEADERS([uv.h], [], [AC_MSG_ERROR([Header file uv.h is required.])])
+	AC_CHECK_LIB([uv], [uv_version], [], [AC_MSG_ERROR([libuv is required.])])
 ])