diff --git a/src/cli.cpp b/src/cli.cpp
index fec77d1..24ed37e 100644
--- a/src/cli.cpp
+++ b/src/cli.cpp
@@ -138,6 +138,7 @@
     }
     if (const auto& enableFeatures = args["-e"]) {
         namespace x3 = boost::spirit::x3;
+        std::map<std::string, std::vector<std::string>> toEnable;
         auto grammar = +(x3::char_-":") >> ":" >> +(x3::char_-":");
         for (const auto& enableFeature : enableFeatures.asStringList()) {
             std::pair<std::string, std::string> parsed;
@@ -147,12 +148,15 @@
                 std::cerr << "Error parsing feature enable flags: " << enableFeature << "\n";
                 return 1;
             }
-            try {
-                datastore->enableFeature(parsed.first, parsed.second);
-            } catch (std::runtime_error& ex) {
-                std::cerr << ex.what() << "\n";
-                return 1;
+            toEnable[parsed.first].emplace_back(parsed.second);
+        }
+        try {
+            for (const auto& [moduleName, features] : toEnable) {
+                datastore->setEnabledFeatures(moduleName, features);
             }
+        } catch (std::runtime_error& ex) {
+            std::cerr << ex.what() << "\n";
+            return 1;
         }
     }
 
diff --git a/src/libyang_utils.cpp b/src/libyang_utils.cpp
index a6b22cd..f3881fe 100644
--- a/src/libyang_utils.cpp
+++ b/src/libyang_utils.cpp
@@ -1,130 +1,131 @@
 #include <boost/algorithm/string/predicate.hpp>
 #include <cmath>
+#include <libyang-cpp/Context.hpp>
 #include "datastore_access.hpp"
 #include "libyang_utils.hpp"
 #include "utils.hpp"
 
-leaf_data_ leafValueFromNode(libyang::S_Data_Node_Leaf_List node)
+struct impl_leafValueFromNode {
+    leaf_data_ operator()(const libyang::Empty) const
+    {
+        return empty_{};
+    }
+
+    leaf_data_ operator()(const libyang::Binary& bin) const
+    {
+        return binary_{std::string{bin.base64}};
+    }
+
+    leaf_data_ operator()(const std::vector<libyang::Bit>& bits) const
+    {
+        bits_ res;
+        std::transform(bits.begin(), bits.end(), std::back_inserter(res.m_bits), [] (const libyang::Bit& bit) {
+            return bit.name;
+        });
+        return res;
+    }
+
+    leaf_data_ operator()(const libyang::Enum& enumVal) const
+    {
+        return enum_{enumVal.name};
+    }
+
+    leaf_data_ operator()(const libyang::IdentityRef& identRef) const
+    {
+        return identityRef_{identRef.module, identRef.name};
+    }
+
+    leaf_data_ operator()(const libyang::Decimal64& dec) const
+    {
+        return dec.number * std::pow(10, -dec.digits);
+    }
+
+    leaf_data_ operator()(const std::optional<libyang::DataNode>&) const
+    {
+        throw std::runtime_error("instance-identifier is not supported");
+    }
+
+    template <typename Type>
+    leaf_data_ operator()(const Type& val) const
+    {
+        return val;
+    }
+};
+
+leaf_data_ leafValueFromNode(libyang::DataNodeTerm node)
 {
-    std::function<leaf_data_(libyang::S_Data_Node_Leaf_List)> impl = [&impl](libyang::S_Data_Node_Leaf_List node) -> leaf_data_ {
-        // value_type() is what's ACTUALLY stored inside `node`
-        // Leafrefs sometimes don't hold a reference to another, but they have the actual pointed-to value.
-        switch (node->value_type()) {
-        case LY_TYPE_ENUM:
-            return enum_{node->value()->enm()->name()};
-        case LY_TYPE_UINT8:
-            return node->value()->uint8();
-        case LY_TYPE_UINT16:
-            return node->value()->uint16();
-        case LY_TYPE_UINT32:
-            return node->value()->uint32();
-        case LY_TYPE_UINT64:
-            return node->value()->uint64();
-        case LY_TYPE_INT8:
-            return node->value()->int8();
-        case LY_TYPE_INT16:
-            return node->value()->int16();
-        case LY_TYPE_INT32:
-            return node->value()->int32();
-        case LY_TYPE_INT64:
-            return node->value()->int64();
-        case LY_TYPE_DEC64: {
-            auto v = node->value()->dec64();
-            return v.value * std::pow(10, -v.digits);
-        }
-        case LY_TYPE_BOOL:
-            return node->value()->bln();
-        case LY_TYPE_STRING:
-            return std::string{node->value()->string()};
-        case LY_TYPE_BINARY:
-            return binary_{node->value()->binary()};
-        case LY_TYPE_IDENT:
-            return identityRef_{node->value()->ident()->module()->name(), node->value()->ident()->name()};
-        case LY_TYPE_EMPTY:
-            return empty_{};
-        case LY_TYPE_LEAFREF: {
-            auto refsTo = node->value()->leafref();
-            assert(refsTo);
-            return impl(std::make_shared<libyang::Data_Node_Leaf_List>(node->value()->leafref()));
-        }
-        case LY_TYPE_BITS: {
-            auto bits = node->value()->bit();
-            std::vector<libyang::S_Type_Bit> filterNull;
-            std::copy_if(bits.begin(), bits.end(), std::back_inserter(filterNull), [](auto bit) { return bit; });
-            bits_ res;
-            std::transform(filterNull.begin(), filterNull.end(), std::inserter(res.m_bits, res.m_bits.end()), [](const auto& bit) { return bit->name(); });
-            return bits_{res};
-        }
-        default:
-            return std::string{"(can't print)"};
-        }
-    };
-    return impl(node);
+    return std::visit(impl_leafValueFromNode{},node.value());
 }
 
 namespace {
-void impl_lyNodesToTree(DatastoreAccess::Tree& res, const std::vector<std::shared_ptr<libyang::Data_Node>> items, std::optional<std::string> ignoredXPathPrefix)
+template <typename CollectionType>
+void impl_lyNodesToTree(DatastoreAccess::Tree& res, CollectionType items, std::optional<std::string> ignoredXPathPrefix)
 {
     auto stripXPathPrefix = [&ignoredXPathPrefix](auto path) {
         return ignoredXPathPrefix && path.find(*ignoredXPathPrefix) != std::string::npos ? path.substr(ignoredXPathPrefix->size()) : path;
     };
 
     for (const auto& it : items) {
-        if (it->schema()->nodetype() == LYS_CONTAINER) {
-            if (libyang::Schema_Node_Container{it->schema()}.presence()) {
+        if (it.schema().nodeType() == libyang::NodeType::Container) {
+            if (it.schema().asContainer().isPresence()) {
                 // The fact that the container is included in the data tree
                 // means that it is present and I don't need to check any
                 // value.
-                res.emplace_back(stripXPathPrefix(it->path()), special_{SpecialValue::PresenceContainer});
+                res.emplace_back(stripXPathPrefix(std::string{it.path()}), special_{SpecialValue::PresenceContainer});
             }
         }
-        if (it->schema()->nodetype() == LYS_LIST) {
-            res.emplace_back(stripXPathPrefix(it->path()), special_{SpecialValue::List});
+        if (it.schema().nodeType() == libyang::NodeType::List) {
+            res.emplace_back(stripXPathPrefix(std::string{it.path()}), special_{SpecialValue::List});
         }
-        if (it->schema()->nodetype() == LYS_LEAF || it->schema()->nodetype() == LYS_LEAFLIST) {
-            auto leaf = std::make_shared<libyang::Data_Node_Leaf_List>(it);
-            auto value = leafValueFromNode(leaf);
-            res.emplace_back(stripXPathPrefix(it->path()), value);
+        if (it.schema().nodeType() == libyang::NodeType::Leaf || it.schema().nodeType() == libyang::NodeType::Leaflist) {
+            auto term = it.asTerm();
+            auto value = leafValueFromNode(term);
+            res.emplace_back(stripXPathPrefix(std::string{it.path()}), value);
         }
     }
 }
 }
 
-void lyNodesToTree(DatastoreAccess::Tree& res, const std::vector<std::shared_ptr<libyang::Data_Node>> items, std::optional<std::string> ignoredXPathPrefix)
+template <typename CollectionType>
+void lyNodesToTree(DatastoreAccess::Tree& res, CollectionType items, std::optional<std::string> ignoredXPathPrefix)
 {
-    for (auto it = items.begin(); it < items.end(); it++) {
-        if ((*it)->schema()->nodetype() == LYS_LEAFLIST) {
-            auto leafListPath = stripLeafListValueFromPath((*it)->path());
+    for (auto it = items.begin(); it != items.end(); /* nothing */) {
+        if ((*it).schema().nodeType() == libyang::NodeType::Leaflist) {
+            auto leafListPath = stripLeafListValueFromPath(std::string{(*it).path()});
             res.emplace_back(leafListPath, special_{SpecialValue::LeafList});
-            while (it != items.end() && boost::starts_with((*it)->path(), leafListPath)) {
-                impl_lyNodesToTree(res, (*it)->tree_dfs(), ignoredXPathPrefix);
+            while (it != items.end() && boost::starts_with(std::string{(*it).path()}, leafListPath)) {
+                impl_lyNodesToTree(res, it->childrenDfs(), ignoredXPathPrefix);
                 it++;
             }
         } else {
-            impl_lyNodesToTree(res, (*it)->tree_dfs(), ignoredXPathPrefix);
+            impl_lyNodesToTree(res, it->childrenDfs(), ignoredXPathPrefix);
+            it++;
         }
     }
 }
 
-DatastoreAccess::Tree rpcOutputToTree(const std::string& rpcPath, libyang::S_Data_Node output)
+using SiblingColl = libyang::Collection<libyang::DataNode, libyang::IterationType::Sibling>;
+using DfsColl = libyang::Collection<libyang::DataNode, libyang::IterationType::Dfs>;
+
+template
+void lyNodesToTree<SiblingColl>(DatastoreAccess::Tree& res, SiblingColl items, std::optional<std::string> ignoredXPathPrefix);
+template
+void lyNodesToTree<DfsColl>(DatastoreAccess::Tree& res, DfsColl items, std::optional<std::string> ignoredXPathPrefix);
+template
+void lyNodesToTree<libyang::Set<libyang::DataNode>>(DatastoreAccess::Tree& res, libyang::Set<libyang::DataNode> items, std::optional<std::string> ignoredXPathPrefix);
+
+DatastoreAccess::Tree rpcOutputToTree(libyang::DataNode output)
 {
     DatastoreAccess::Tree res;
-    if (output) {
-        // The output is "some top-level node". If we actually want the output of our RPC/action we need to use
-        // find_path.  Also, our `path` is fully prefixed, but the output paths aren't. So we use outputNode->path() to
-        // get the unprefixed path.
-
-        auto outputNode = output->find_path(rpcPath.c_str())->data().front();
-        lyNodesToTree(res, {outputNode}, joinPaths(outputNode->path(), "/"));
-    }
+    lyNodesToTree(res, output.siblings(), joinPaths(std::string{output.path()}, "/"));
     return res;
 }
 
-libyang::S_Data_Node treeToRpcInput(libyang::S_Context ctx, const std::string& path, DatastoreAccess::Tree in)
+libyang::DataNode treeToRpcInput(libyang::Context ctx, const std::string& path, DatastoreAccess::Tree in)
 {
-    auto root = std::make_shared<libyang::Data_Node>(ctx, path.c_str(), nullptr, LYD_ANYDATA_CONSTSTRING, LYD_PATH_OPT_UPDATE);
+    auto root = ctx.newPath(path.c_str(), nullptr, libyang::CreationOptions::Update);
     for (const auto& [k, v] : in) {
-        root->new_path(ctx, k.c_str(), leafDataToString(v).c_str(), LYD_ANYDATA_CONSTSTRING, LYD_PATH_OPT_UPDATE);
+        root.newPath(k.c_str(), leafDataToString(v).c_str(), libyang::CreationOptions::Update);
     }
 
     return root;
diff --git a/src/libyang_utils.hpp b/src/libyang_utils.hpp
index b5f5e96..8a470c7 100644
--- a/src/libyang_utils.hpp
+++ b/src/libyang_utils.hpp
@@ -5,11 +5,12 @@
  *
 */
 
-#include <libyang/Tree_Data.hpp>
+#include <libyang-cpp/DataNode.hpp>
 #include "ast_values.hpp"
 #include "datastore_access.hpp"
 
-leaf_data_ leafValueFromNode(libyang::S_Data_Node_Leaf_List node);
-void lyNodesToTree(DatastoreAccess::Tree& res, const std::vector<std::shared_ptr<libyang::Data_Node>> items, std::optional<std::string> ignoredXPathPrefix = std::nullopt);
-libyang::S_Data_Node treeToRpcInput(libyang::S_Context ctx, const std::string& path, DatastoreAccess::Tree in);
-DatastoreAccess::Tree rpcOutputToTree(const std::string& rpcPath, libyang::S_Data_Node output);
+leaf_data_ leafValueFromNode(libyang::DataNodeTerm node);
+template <typename CollectionType>
+void lyNodesToTree(DatastoreAccess::Tree& res, CollectionType items, std::optional<std::string> ignoredXPathPrefix = std::nullopt);
+libyang::DataNode treeToRpcInput(libyang::Context ctx, const std::string& path, DatastoreAccess::Tree in);
+DatastoreAccess::Tree rpcOutputToTree(libyang::DataNode output);
diff --git a/src/netconf-client.cpp b/src/netconf-client.cpp
index 4638bcb..0685db6 100644
--- a/src/netconf-client.cpp
+++ b/src/netconf-client.cpp
@@ -7,7 +7,8 @@
 */
 
 #include <cstring>
-#include <libyang/Tree_Data.hpp>
+#include <libyang-cpp/Context.hpp>
+#include <libyang-cpp/DataNode.hpp>
 #include <mutex>
 extern "C" {
 #include <nc_client.h>
@@ -58,15 +59,6 @@
 
 static std::mutex clientOptions;
 
-inline void custom_free_nc_reply_data(nc_reply_data* reply)
-{
-    nc_reply_free(reinterpret_cast<nc_reply*>(reply));
-}
-inline void custom_free_nc_reply_error(nc_reply_error* reply)
-{
-    nc_reply_free(reinterpret_cast<nc_reply*>(reply));
-}
-
 char* ssh_auth_interactive_cb(const char* auth_name, const char* instruction, const char* prompt, int echo, void* priv)
 {
     const auto cb = static_cast<const client::KbdInteractiveCb*>(priv);
@@ -74,24 +66,19 @@
     return ::strdup(res.c_str());
 }
 
-template <typename Type> using deleter_type_for = void (*)(Type*);
-template <typename Type> deleter_type_for<Type> const deleter_for;
-
-template <> const auto deleter_for<nc_rpc> = nc_rpc_free;
-template <> const auto deleter_for<nc_reply> = nc_reply_free;
-template <> const auto deleter_for<nc_reply_data> = custom_free_nc_reply_data;
-template <> const auto deleter_for<nc_reply_error> = custom_free_nc_reply_error;
-
-template <typename T>
-using unique_ptr_for = std::unique_ptr<T, decltype(deleter_for<T>)>;
-
-template <typename T>
-auto guarded(T* ptr)
+auto guarded(nc_rpc* ptr)
 {
-    return unique_ptr_for<T>(ptr, deleter_for<T>);
+    return std::unique_ptr<nc_rpc, decltype(&nc_rpc_free)>(ptr, nc_rpc_free);
 }
 
-unique_ptr_for<struct nc_reply> do_rpc(client::Session* session, unique_ptr_for<struct nc_rpc>&& rpc)
+namespace {
+const auto getData_path = "/ietf-netconf-nmda:get-data/data";
+const auto get_path = "/ietf-netconf:get/data";
+}
+
+using managed_rpc = std::invoke_result_t<decltype(guarded), nc_rpc*>;
+
+std::optional<libyang::DataNode> do_rpc(client::Session* session, managed_rpc&& rpc, const char* dataIdentifier)
 {
     uint64_t msgid;
     NC_MSG_TYPE msgtype;
@@ -104,11 +91,11 @@
         throw std::runtime_error{"Timeout sending an RPC"};
     }
 
-    struct nc_reply* raw_reply;
+    lyd_node* raw_reply;
+    lyd_node* envp;
     while (true) {
-        msgtype = nc_recv_reply(session->session_internal(), rpc.get(), msgid, 20000, LYD_OPT_DESTRUCT | LYD_OPT_NOSIBLINGS, &raw_reply);
-        auto reply = guarded(raw_reply);
-        raw_reply = nullptr;
+        msgtype = nc_recv_reply(session->session_internal(), rpc.get(), msgid, 20000, &envp, &raw_reply);
+        auto replyInfo = libyang::wrapRawNode(envp);
 
         switch (msgtype) {
         case NC_MSG_ERROR:
@@ -120,76 +107,75 @@
         case NC_MSG_NOTIF:
             continue;
         default:
-            return reply;
+            if (!raw_reply) { // <ok> reply, or empty data node, or error
+                std::string msg;
+                for (const auto& child : replyInfo.child()->siblings()) {
+                    if (child.asOpaque().name().name == "rpc-error") {
+                        for (const auto& error : child.childrenDfs()) {
+                            if (error.asOpaque().name().name == "error-message") {
+                                msg += "Error: ";
+                                msg += error.asOpaque().value();
+                            }
+
+                            if (error.asOpaque().name().name == "error-path") {
+                                msg += "Path: ";
+                                msg += error.asOpaque().value();
+                            }
+
+                            if (error.asOpaque().name().name == "error-type") {
+                                msg += "Type: ";
+                                msg += error.asOpaque().value();
+                            }
+
+                            if (error.asOpaque().name().name == "error-tag") {
+                                msg += "Tag: ";
+                                msg += error.asOpaque().value();
+                            }
+
+                            if (error.asOpaque().name().name == "error-app-tag") {
+                                msg += "App-tag: ";
+                                msg += error.asOpaque().value();
+                            }
+                        }
+
+                        msg += "\n";
+                    }
+                }
+
+                if (!msg.empty()) {
+                    throw client::ReportedError{msg};
+                }
+
+                return std::nullopt;
+            }
+            auto wrapped = libyang::wrapRawNode(raw_reply);
+
+            // If we have a dataIdentifier, then we'll need to look for it.
+            // Some operations don't have that, and then the result data are just the wrapped node.
+            if (!dataIdentifier) {
+                return wrapped;
+            }
+
+            auto anydataValue = wrapped.findPath(dataIdentifier, libyang::OutputNodes::Yes)->asAny().releaseValue();
+
+            // If there's no anydata value, then that means we get empty (but valid) data.
+            if (!anydataValue) {
+                return std::nullopt;
+            }
+
+            return std::get<libyang::DataNode>(*anydataValue);
         }
     }
     __builtin_unreachable();
 }
 
-client::ReportedError make_error(unique_ptr_for<struct nc_reply>&& reply)
+void do_rpc_ok(client::Session* session, managed_rpc&& rpc)
 {
-    if (reply->type != NC_RPL_ERROR) {
-        throw std::logic_error{"Cannot extract an error from a non-error server reply"};
-    }
-
-    auto errorReply = guarded(reinterpret_cast<struct nc_reply_error*>(reply.release()));
-
-    // TODO: capture the error details, not just that human-readable string
-    std::ostringstream ss;
-    ss << "Server error:" << std::endl;
-    for (uint32_t i = 0; i < errorReply->count; ++i) {
-        const auto e = errorReply->err[i];
-        ss << " #" << i << ": " << e.message;
-        if (e.path) {
-            ss << " (XPath " << e.path << ")";
-        }
-        ss << std::endl;
-    }
-    return client::ReportedError{ss.str()};
-}
-
-std::optional<unique_ptr_for<struct nc_reply_data>> do_rpc_data_or_ok(client::Session* session, unique_ptr_for<struct nc_rpc>&& rpc)
-{
-    auto x = do_rpc(session, std::move(rpc));
-
-    switch (x->type) {
-    case NC_RPL_DATA:
-        return guarded(reinterpret_cast<struct nc_reply_data*>(x.release()));
-    case NC_RPL_OK:
-        return std::nullopt;
-    case NC_RPL_ERROR:
-        throw make_error(std::move(x));
-    default:
-        throw std::runtime_error{"Unhandled reply type"};
-    }
-}
-
-unique_ptr_for<struct nc_reply_data> do_rpc_data(client::Session* session, unique_ptr_for<struct nc_rpc>&& rpc)
-{
-    auto x = do_rpc_data_or_ok(session, std::move(rpc));
-    if (!x) {
-        throw std::runtime_error{"Received OK instead of a data reply"};
-    }
-    return std::move(*x);
-}
-
-void do_rpc_ok(client::Session* session, unique_ptr_for<struct nc_rpc>&& rpc)
-{
-    auto x = do_rpc_data_or_ok(session, std::move(rpc));
+    auto x = do_rpc(session, std::move(rpc), nullptr);
     if (x) {
         throw std::runtime_error{"Unexpected DATA reply"};
     }
 }
-
-std::shared_ptr<libyang::Data_Node> do_get(client::Session* session, unique_ptr_for<nc_rpc> rpc)
-{
-    auto reply = impl::do_rpc_data(session, std::move(rpc));
-    auto dataNode = libyang::create_new_Data_Node(reply->data);
-    // TODO: can we do without copying?
-    // If we just default-construct a new node (or use the create_new_Data_Node) and then set reply->data to nullptr,
-    // there are mem leaks and even libnetconf2 complains loudly.
-    return dataNode ? dataNode->dup_withsiblings(1) : nullptr;
-}
 }
 
 namespace client {
@@ -210,9 +196,9 @@
     return m_session;
 }
 
-libyang::S_Context Session::libyangContext()
+libyang::Context Session::libyangContext()
 {
-    return std::make_shared<libyang::Context>(nc_session_get_ctx(m_session), nullptr);
+    return libyang::createUnmanagedContext(const_cast<ly_ctx*>(nc_session_get_ctx(m_session)), nullptr);
 }
 
 Session::Session(struct nc_session* session)
@@ -298,13 +284,13 @@
     return res;
 }
 
-std::shared_ptr<libyang::Data_Node> Session::get(const std::optional<std::string>& filter)
+std::optional<libyang::DataNode> Session::get(const std::optional<std::string>& filter)
 {
     auto rpc = impl::guarded(nc_rpc_get(filter ? filter->c_str() : nullptr, NC_WD_ALL, NC_PARAMTYPE_CONST));
     if (!rpc) {
         throw std::runtime_error("Cannot create get RPC");
     }
-    return impl::do_get(this, std::move(rpc));
+    return impl::do_rpc(this, std::move(rpc), impl::get_path);
 }
 
 const char* datastoreToString(NmdaDatastore datastore)
@@ -322,13 +308,13 @@
     __builtin_unreachable();
 }
 
-std::shared_ptr<libyang::Data_Node> Session::getData(const NmdaDatastore datastore, const std::optional<std::string>& filter)
+std::optional<libyang::DataNode> Session::getData(const NmdaDatastore datastore, const std::optional<std::string>& filter)
 {
     auto rpc = impl::guarded(nc_rpc_getdata(datastoreToString(datastore), filter ? filter->c_str() : nullptr, nullptr, nullptr, 0, 0, 0, 0, NC_WD_ALL, NC_PARAMTYPE_CONST));
     if (!rpc) {
         throw std::runtime_error("Cannot create get RPC");
     }
-    return impl::do_get(this, std::move(rpc));
+    return impl::do_rpc(this, std::move(rpc), impl::getData_path);
 }
 
 void Session::editData(const NmdaDatastore datastore, const std::string& data)
@@ -340,34 +326,6 @@
     return impl::do_rpc_ok(this, std::move(rpc));
 }
 
-std::string Session::getSchema(const std::string_view identifier, const std::optional<std::string_view> version)
-{
-    auto rpc = impl::guarded(nc_rpc_getschema(identifier.data(), version ? version.value().data() : nullptr, nullptr, NC_PARAMTYPE_CONST));
-    if (!rpc) {
-        throw std::runtime_error("Cannot create get-schema RPC");
-    }
-    auto reply = impl::do_rpc_data(this, std::move(rpc));
-
-    auto node = libyang::create_new_Data_Node(reply->data)->dup_withsiblings(1);
-    auto set = node->find_path("data");
-    for (auto node : set->data()) {
-        if (node->schema()->nodetype() == LYS_ANYXML) {
-            libyang::Data_Node_Anydata anydata(node);
-            return anydata.value().str;
-        }
-    }
-    throw std::runtime_error("Got a reply to get-schema, but it didn't contain the required schema");
-}
-
-std::shared_ptr<libyang::Data_Node> Session::getConfig(const NC_DATASTORE datastore, const std::optional<const std::string> filter)
-{
-    auto rpc = impl::guarded(nc_rpc_getconfig(datastore, filter ? filter->c_str() : nullptr, NC_WD_ALL, NC_PARAMTYPE_CONST));
-    if (!rpc) {
-        throw std::runtime_error("Cannot create get-config RPC");
-    }
-    return impl::do_get(this, std::move(rpc));
-}
-
 void Session::editConfig(const NC_DATASTORE datastore,
                          const NC_RPC_EDIT_DFLTOP defaultOperation,
                          const NC_RPC_EDIT_TESTOPT testOption,
@@ -408,19 +366,14 @@
     impl::do_rpc_ok(this, std::move(rpc));
 }
 
-std::shared_ptr<libyang::Data_Node> Session::rpc_or_action(const std::string& xmlData)
+std::optional<libyang::DataNode> Session::rpc_or_action(const std::string& xmlData)
 {
     auto rpc = impl::guarded(nc_rpc_act_generic_xml(xmlData.c_str(), NC_PARAMTYPE_CONST));
     if (!rpc) {
         throw std::runtime_error("Cannot create generic RPC");
     }
-    auto reply = impl::do_rpc_data_or_ok(this, std::move(rpc));
-    if (reply) {
-        auto dataNode = libyang::create_new_Data_Node((*reply)->data);
-        return dataNode->dup_withsiblings(1);
-    } else {
-        return nullptr;
-    }
+
+    return impl::do_rpc(this, std::move(rpc), nullptr);
 }
 
 void Session::copyConfig(const NC_DATASTORE source, const NC_DATASTORE destination)
diff --git a/src/netconf-client.hpp b/src/netconf-client.hpp
index 839c528..5a16cf2 100644
--- a/src/netconf-client.hpp
+++ b/src/netconf-client.hpp
@@ -12,8 +12,8 @@
 struct nc_session;
 
 namespace libyang {
-class Data_Node;
 class Context;
+class DataNode;
 }
 
 namespace libnetconf {
@@ -46,11 +46,8 @@
     static std::unique_ptr<Session> connectSocket(const std::string& path);
     static std::unique_ptr<Session> connectFd(const int source, const int sink);
     [[nodiscard]] std::vector<std::string_view> capabilities() const;
-    std::shared_ptr<libyang::Data_Node> getConfig(const NC_DATASTORE datastore,
-                                                  const std::optional<const std::string> filter = std::nullopt); // TODO: arguments...
-    std::shared_ptr<libyang::Data_Node> get(const std::optional<std::string>& filter = std::nullopt);
-    std::shared_ptr<libyang::Data_Node> getData(const NmdaDatastore datastore, const std::optional<std::string>& filter = std::nullopt);
-    std::string getSchema(const std::string_view identifier, const std::optional<std::string_view> version);
+    std::optional<libyang::DataNode> get(const std::optional<std::string>& filter = std::nullopt);
+    std::optional<libyang::DataNode> getData(const NmdaDatastore datastore, const std::optional<std::string>& filter = std::nullopt);
     void editConfig(const NC_DATASTORE datastore,
                     const NC_RPC_EDIT_DFLTOP defaultOperation,
                     const NC_RPC_EDIT_TESTOPT testOption,
@@ -58,12 +55,12 @@
                     const std::string& data);
     void editData(const NmdaDatastore datastore, const std::string& data);
     void copyConfigFromString(const NC_DATASTORE target, const std::string& data);
-    std::shared_ptr<libyang::Data_Node> rpc_or_action(const std::string& xmlData);
+    std::optional<libyang::DataNode> rpc_or_action(const std::string& xmlData);
     void copyConfig(const NC_DATASTORE source, const NC_DATASTORE destination);
     void commit();
     void discard();
 
-    std::shared_ptr<libyang::Context> libyangContext();
+    libyang::Context libyangContext();
     struct nc_session* session_internal(); // FIXME: remove me
 protected:
     struct nc_session* m_session;
diff --git a/src/netconf_access.cpp b/src/netconf_access.cpp
index a6dbb7c..2b76e50 100644
--- a/src/netconf_access.cpp
+++ b/src/netconf_access.cpp
@@ -5,8 +5,6 @@
  *
 */
 
-#include <libyang/Libyang.hpp>
-#include <libyang/Tree_Data.hpp>
 #include "libyang_utils.hpp"
 #include "netconf-client.hpp"
 #include "netconf_access.hpp"
@@ -55,7 +53,7 @@
     }();
 
     if (config) {
-        lyNodesToTree(res, config->tree_for());
+        lyNodesToTree(res, config->siblings());
     }
     return res;
 }
@@ -107,22 +105,28 @@
 void NetconfAccess::setLeaf(const std::string& path, leaf_data_ value)
 {
     auto lyValue = value.type() == typeid(empty_) ? std::nullopt : std::optional(leafDataToString(value));
-    auto node = m_schema->dataNodeFromPath(path, lyValue);
-    doEditFromDataNode(node);
+    auto nodes = m_schema->dataNodeFromPath(path, lyValue);
+    doEditFromDataNode(*nodes.createdParent);
 }
 
 void NetconfAccess::createItem(const std::string& path)
 {
-    auto node = m_schema->dataNodeFromPath(path);
-    doEditFromDataNode(node);
+    auto nodes = m_schema->dataNodeFromPath(path);
+    doEditFromDataNode(*nodes.createdParent);
 }
 
 void NetconfAccess::deleteItem(const std::string& path)
 {
-    auto node = m_schema->dataNodeFromPath(path);
-    auto container = *(node->find_path(path.c_str())->data().begin());
-    container->insert_attr(m_schema->getYangModule("ietf-netconf"), "operation", "delete");
-    doEditFromDataNode(node);
+    auto nodes = m_schema->dataNodeFromPath(path);
+
+    // When deleting leafs, `nodes.newNode` is opaque, because the leaf does not have a value. We need to use
+    // newAttrOpaqueJSON for opaque leafs.
+    if (nodes.createdNode->isOpaque()) {
+        nodes.createdNode->newAttrOpaqueJSON("ietf-netconf", "ietf-netconf:operation", "delete");
+    } else {
+        nodes.createdNode->newMeta(*m_schema->getYangModule("ietf-netconf"), "operation", "delete");
+    }
+    doEditFromDataNode(*nodes.createdParent);
 }
 
 struct impl_toYangInsert {
@@ -143,29 +147,29 @@
 
 void NetconfAccess::moveItem(const std::string& source, std::variant<yang::move::Absolute, yang::move::Relative> move)
 {
-    auto node = m_schema->dataNodeFromPath(source);
-    auto sourceNode = *(node->find_path(source.c_str())->data().begin());
-    auto yangModule = m_schema->getYangModule("yang");
-    sourceNode->insert_attr(yangModule, "insert", toYangInsert(move).c_str());
+    auto nodes = m_schema->dataNodeFromPath(source);
+    auto sourceNode = *(nodes.createdNode->findPath(source.c_str()));
+    auto yangModule = *m_schema->getYangModule("yang");
+    sourceNode.newMeta(yangModule, "insert", toYangInsert(move).c_str());
 
     if (std::holds_alternative<yang::move::Relative>(move)) {
         auto relative = std::get<yang::move::Relative>(move);
         if (m_schema->nodeType(source) == yang::NodeTypes::LeafList) {
-            sourceNode->insert_attr(yangModule, "value", leafDataToString(relative.m_path.at(".")).c_str());
+            sourceNode.newMeta(yangModule, "value", leafDataToString(relative.m_path.at(".")).c_str());
         } else {
-            sourceNode->insert_attr(yangModule, "key", instanceToString(relative.m_path, node->node_module()->name()).c_str());
+            sourceNode.newMeta(yangModule, "key", instanceToString(relative.m_path, std::string{nodes.createdNode->schema().module().name()}).c_str());
         }
     }
     doEditFromDataNode(sourceNode);
 }
 
-void NetconfAccess::doEditFromDataNode(std::shared_ptr<libyang::Data_Node> dataNode)
+void NetconfAccess::doEditFromDataNode(libyang::DataNode dataNode)
 {
-    auto data = dataNode->print_mem(LYD_XML, 0);
+    auto data = dataNode.printStr(libyang::DataFormat::XML, libyang::PrintFlags::WithSiblings);
     if (m_serverHasNMDA) {
-        m_session->editData(targetToDs_set(m_target), data);
+        m_session->editData(targetToDs_set(m_target), std::string{*data});
     } else {
-        m_session->editConfig(NC_DATASTORE_CANDIDATE, NC_RPC_EDIT_DFLTOP_MERGE, NC_RPC_EDIT_TESTOPT_TESTSET, NC_RPC_EDIT_ERROPT_STOP, data);
+        m_session->editConfig(NC_DATASTORE_CANDIDATE, NC_RPC_EDIT_DFLTOP_MERGE, NC_RPC_EDIT_TESTOPT_TESTSET, NC_RPC_EDIT_ERROPT_STOP, std::string{*data});
     }
 }
 
@@ -182,10 +186,13 @@
 DatastoreAccess::Tree NetconfAccess::execute(const std::string& path, const Tree& input)
 {
     auto inputNode = treeToRpcInput(m_session->libyangContext(), path, input);
-    auto data = inputNode->print_mem(LYD_XML, 0);
+    auto data = inputNode.printStr(libyang::DataFormat::XML, libyang::PrintFlags::WithSiblings);
 
-    auto output = m_session->rpc_or_action(data);
-    return rpcOutputToTree(path, output);
+    auto output = m_session->rpc_or_action(std::string{*data});
+    if (!output) {
+        return {};
+    }
+    return rpcOutputToTree(*output);
 }
 
 NC_DATASTORE toNcDatastore(Datastore datastore)
@@ -212,41 +219,41 @@
 std::vector<ListInstance> NetconfAccess::listInstances(const std::string& path)
 {
     std::vector<ListInstance> res;
-    auto list = m_schema->dataNodeFromPath(path);
+    auto keys = m_session->libyangContext().findXPath(path.c_str()).front().asList().keys();
+    auto nodes = m_session->libyangContext().newPath2(path.c_str(), nullptr, libyang::CreationOptions::Opaque);
 
-    // This inserts selection nodes - I only want keys not other data
-    // To get the keys, I have to call find_path here - otherwise I would get keys of a top-level node (which might not even be a list)
-    auto keys = libyang::Schema_Node_List{(*(list->find_path(path.c_str())->data().begin()))->schema()}.keys();
+    // Here we create a tree with "selection leafs" for all they keys of our wanted list. These leafs tell NETCONF, that
+    // we only want the list's keys and not any other data.
     for (const auto& keyLeaf : keys) {
-        // Have to call find_path here - otherwise I'll have the list, not the leaf inside it
-        auto selectionLeaf = *(m_schema->dataNodeFromPath(keyLeaf->path())->find_path(keyLeaf->path().c_str())->data().begin());
-        auto actualList = *(list->find_path(path.c_str())->data().begin());
-        actualList->insert(selectionLeaf);
+        // Selection leafs need to be inserted directly to the list using relative paths, that's why `newNode` is used
+        // here.
+        nodes.createdNode->newPath(keyLeaf.name().data(), nullptr, libyang::CreationOptions::Opaque);
     }
 
-    auto instances = m_session->get(list->print_mem(LYD_XML, 0));
+    // Have to use `newParent` in case our wanted list is a nested list. With `newNode` I would only send the inner
+    // nested list and not the whole tree.
+    auto instances = m_session->get(std::string{*nodes.createdParent->printStr(libyang::DataFormat::XML, libyang::PrintFlags::WithSiblings)});
 
     if (!instances) {
         return res;
     }
 
-    for (const auto& instance : instances->find_path(path.c_str())->data()) {
+    for (const auto& instance : instances->findXPath(path.c_str())) {
         ListInstance instanceRes;
 
-        // I take the first child here, because the first element (the parent of the child()) will be the list
-        for (const auto& keyLeaf : instance->child()->tree_for()) {
+        for (const auto& keyLeaf : instance.child()->siblings()) {
             // FIXME: even though we specified we only want the key leafs, Netopeer disregards that and sends more data,
             // even lists and other stuff. We only want keys, so filter out non-leafs and non-keys
             // https://github.com/CESNET/netopeer2/issues/825
-            if (keyLeaf->schema()->nodetype() != LYS_LEAF) {
+            if (keyLeaf.schema().nodeType() != libyang::NodeType::Leaf) {
                 continue;
             }
-            if (!std::make_shared<libyang::Schema_Node_Leaf>(keyLeaf->schema())->is_key()) {
+            if (!keyLeaf.schema().asLeaf().isKey()) {
                 continue;
             }
 
-            auto leafData = std::make_shared<libyang::Data_Node_Leaf_List>(keyLeaf);
-            instanceRes.insert({leafData->schema()->name(), leafValueFromNode(leafData)});
+            auto leafData = keyLeaf.asTerm();
+            instanceRes.insert({std::string{leafData.schema().name()}, leafValueFromNode(leafData)});
         }
         res.emplace_back(instanceRes);
     }
@@ -260,5 +267,10 @@
     if (!config) {
         return "";
     }
-    return config->print_mem(format == DataFormat::Xml ? LYD_XML : LYD_JSON, LYP_WITHSIBLINGS | LYP_FORMAT);
+    auto str = config->printStr(format == DataFormat::Xml ? libyang::DataFormat::XML : libyang::DataFormat::JSON, libyang::PrintFlags::WithSiblings);
+    if (!str) {
+        return "";
+    }
+
+    return std::string{*str};
 }
diff --git a/src/netconf_access.hpp b/src/netconf_access.hpp
index 43ca1e8..eb678d5 100644
--- a/src/netconf_access.hpp
+++ b/src/netconf_access.hpp
@@ -21,10 +21,6 @@
 }
 }
 
-namespace libyang {
-class Data_Node;
-}
-
 class Schema;
 class YangSchema;
 
@@ -57,7 +53,7 @@
 private:
     std::vector<ListInstance> listInstances(const std::string& path) override;
 
-    void doEditFromDataNode(std::shared_ptr<libyang::Data_Node> dataNode);
+    void doEditFromDataNode(libyang::DataNode dataNode);
 
     void checkNMDA();
 
diff --git a/src/sysrepo_access.cpp b/src/sysrepo_access.cpp
index bbdf6d1..34d255a 100644
--- a/src/sysrepo_access.cpp
+++ b/src/sysrepo_access.cpp
@@ -7,86 +7,34 @@
 */
 
 #include <experimental/iterator>
-#include <libyang/Tree_Data.hpp>
-#include <libyang/Tree_Schema.hpp>
 #include <sstream>
 #include <sysrepo-cpp/Session.hpp>
+#include <sysrepo-cpp/utils/exception.hpp>
 #include "libyang_utils.hpp"
 #include "sysrepo_access.hpp"
 #include "utils.hpp"
 #include "yang_schema.hpp"
 
-const auto OPERATION_TIMEOUT_MS = 1000;
-
-struct valFromValue : boost::static_visitor<sysrepo::S_Val> {
-    sysrepo::S_Val operator()(const enum_& value) const
-    {
-        return std::make_shared<sysrepo::Val>(value.m_value.c_str(), SR_ENUM_T);
-    }
-
-    sysrepo::S_Val operator()(const binary_& value) const
-    {
-        return std::make_shared<sysrepo::Val>(value.m_value.c_str(), SR_BINARY_T);
-    }
-
-    sysrepo::S_Val operator()(const empty_) const
-    {
-        return std::make_shared<sysrepo::Val>(nullptr, SR_LEAF_EMPTY_T);
-    }
-
-    sysrepo::S_Val operator()(const identityRef_& value) const
-    {
-        auto res = value.m_prefix ? (value.m_prefix.value().m_name + ":" + value.m_value) : value.m_value;
-        return std::make_shared<sysrepo::Val>(res.c_str(), SR_IDENTITYREF_T);
-    }
-
-    sysrepo::S_Val operator()(const special_& value) const
-    {
-        throw std::runtime_error("Tried constructing S_Val from a " + specialValueToString(value));
-    }
-
-    sysrepo::S_Val operator()(const std::string& value) const
-    {
-        return std::make_shared<sysrepo::Val>(value.c_str());
-    }
-
-    sysrepo::S_Val operator()(const bits_& value) const
-    {
-        std::stringstream ss;
-        std::copy(value.m_bits.begin(), value.m_bits.end(), std::experimental::make_ostream_joiner(ss, " "));
-        return std::make_shared<sysrepo::Val>(ss.str().c_str(), SR_BITS_T);
-    }
-
-    template <typename T>
-    sysrepo::S_Val operator()(const T& value) const
-    {
-        return std::make_shared<sysrepo::Val>(value);
-    }
-};
+const auto OPERATION_TIMEOUT_MS = std::chrono::milliseconds{1000};
 
 SysrepoAccess::~SysrepoAccess() = default;
 
-sr_datastore_t toSrDatastore(Datastore datastore)
+sysrepo::Datastore toSrDatastore(Datastore datastore)
 {
     switch (datastore) {
     case Datastore::Running:
-        return SR_DS_RUNNING;
+        return sysrepo::Datastore::Running;
     case Datastore::Startup:
-        return SR_DS_STARTUP;
+        return sysrepo::Datastore::Startup;
     }
     __builtin_unreachable();
 }
 
 SysrepoAccess::SysrepoAccess()
-    : m_connection(std::make_shared<sysrepo::Connection>())
-    , m_session(std::make_shared<sysrepo::Session>(m_connection))
-    , m_schema(std::make_shared<YangSchema>(m_session->get_context()))
+    : m_connection()
+    , m_session(m_connection.sessionStart())
+    , m_schema(std::make_shared<YangSchema>(m_session.getContext()))
 {
-    try {
-        m_session = std::make_shared<sysrepo::Session>(m_connection);
-    } catch (sysrepo::sysrepo_exception& ex) {
-        reportErrors();
-    }
 }
 
 namespace {
@@ -94,11 +42,11 @@
 {
     switch (target) {
     case DatastoreTarget::Operational:
-        return SR_DS_OPERATIONAL;
+        return sysrepo::Datastore::Operational;
     case DatastoreTarget::Running:
-        return SR_DS_RUNNING;
+        return sysrepo::Datastore::Running;
     case DatastoreTarget::Startup:
-        return SR_DS_STARTUP;
+        return sysrepo::Datastore::Startup;
     }
 
     __builtin_unreachable();
@@ -110,9 +58,9 @@
     case DatastoreTarget::Operational:
     case DatastoreTarget::Running:
         // TODO: Doing candidate here doesn't work, why?
-        return SR_DS_RUNNING;
+        return sysrepo::Datastore::Running;
     case DatastoreTarget::Startup:
-        return SR_DS_STARTUP;
+        return sysrepo::Datastore::Startup;
     }
 
     __builtin_unreachable();
@@ -125,12 +73,12 @@
     Tree res;
 
     try {
-        m_session->session_switch_ds(targetToDs_get(m_target));
-        auto config = m_session->get_data(((path == "/") ? "/*" : path).c_str());
+        m_session.switchDatastore(targetToDs_get(m_target));
+        auto config = m_session.getData(((path == "/") ? "/*" : path).c_str());
         if (config) {
-            lyNodesToTree(res, config->tree_for());
+            lyNodesToTree(res, config->siblings());
         }
-    } catch (sysrepo::sysrepo_exception& ex) {
+    } catch (sysrepo::Error& ex) {
         reportErrors();
     }
     return res;
@@ -139,9 +87,10 @@
 void SysrepoAccess::setLeaf(const std::string& path, leaf_data_ value)
 {
     try {
-        m_session->session_switch_ds(targetToDs_set(m_target));
-        m_session->set_item(path.c_str(), boost::apply_visitor(valFromValue(), value), SR_EDIT_ISOLATE);
-    } catch (sysrepo::sysrepo_exception& ex) {
+        m_session.switchDatastore(targetToDs_set(m_target));
+        auto lyValue = value.type() == typeid(empty_) ? "" : leafDataToString(value);
+        m_session.setItem(path.c_str(), lyValue.c_str(), sysrepo::EditOptions::Isolate);
+    } catch (sysrepo::Error& ex) {
         reportErrors();
     }
 }
@@ -149,9 +98,9 @@
 void SysrepoAccess::createItem(const std::string& path)
 {
     try {
-        m_session->session_switch_ds(targetToDs_set(m_target));
-        m_session->set_item(path.c_str());
-    } catch (sysrepo::sysrepo_exception& ex) {
+        m_session.switchDatastore(targetToDs_set(m_target));
+        m_session.setItem(path.c_str(), nullptr);
+    } catch (sysrepo::Error& ex) {
         reportErrors();
     }
 }
@@ -159,27 +108,28 @@
 void SysrepoAccess::deleteItem(const std::string& path)
 {
     try {
-        // Have to use SR_EDIT_ISOLATE, because deleting something that's been set without committing is not supported
+        // Have to use sysrepo::EditOptions::Isolate, because deleting something that's been set without committing is
+        // not supported.
         // https://github.com/sysrepo/sysrepo/issues/1967#issuecomment-625085090
-        m_session->session_switch_ds(targetToDs_set(m_target));
-        m_session->delete_item(path.c_str(), SR_EDIT_ISOLATE);
-    } catch (sysrepo::sysrepo_exception& ex) {
+        m_session.switchDatastore(targetToDs_set(m_target));
+        m_session.deleteItem(path.c_str(), sysrepo::EditOptions::Isolate);
+    } catch (sysrepo::Error& ex) {
         reportErrors();
     }
 }
 
 struct impl_toSrMoveOp {
-    sr_move_position_t operator()(yang::move::Absolute& absolute)
+    sysrepo::MovePosition operator()(yang::move::Absolute& absolute)
     {
-        return absolute == yang::move::Absolute::Begin ? SR_MOVE_FIRST : SR_MOVE_LAST;
+        return absolute == yang::move::Absolute::Begin ? sysrepo::MovePosition::First : sysrepo::MovePosition::Last;
     }
-    sr_move_position_t operator()(yang::move::Relative& relative)
+    sysrepo::MovePosition operator()(yang::move::Relative& relative)
     {
-        return relative.m_position == yang::move::Relative::Position::After ? SR_MOVE_AFTER : SR_MOVE_BEFORE;
+        return relative.m_position == yang::move::Relative::Position::After ? sysrepo::MovePosition::After : sysrepo::MovePosition::Before;
     }
 };
 
-sr_move_position_t toSrMoveOp(std::variant<yang::move::Absolute, yang::move::Relative> move)
+sysrepo::MovePosition toSrMoveOp(std::variant<yang::move::Absolute, yang::move::Relative> move)
 {
     return std::visit(impl_toSrMoveOp{}, move);
 }
@@ -195,16 +145,16 @@
             destination = instanceToString(relative.m_path);
         }
     }
-    m_session->session_switch_ds(targetToDs_set(m_target));
-    m_session->move_item(source.c_str(), toSrMoveOp(move), destination.c_str(), destination.c_str());
+    m_session.switchDatastore(targetToDs_set(m_target));
+    m_session.moveItem(source.c_str(), toSrMoveOp(move), destination.c_str());
 }
 
 void SysrepoAccess::commitChanges()
 {
     try {
-        m_session->session_switch_ds(targetToDs_set(m_target));
-        m_session->apply_changes(OPERATION_TIMEOUT_MS, 1);
-    } catch (sysrepo::sysrepo_exception& ex) {
+        m_session.switchDatastore(targetToDs_set(m_target));
+        m_session.applyChanges(OPERATION_TIMEOUT_MS);
+    } catch (sysrepo::Error& ex) {
         reportErrors();
     }
 }
@@ -212,25 +162,25 @@
 void SysrepoAccess::discardChanges()
 {
     try {
-        m_session->session_switch_ds(targetToDs_set(m_target));
-        m_session->discard_changes();
-    } catch (sysrepo::sysrepo_exception& ex) {
+        m_session.switchDatastore(targetToDs_set(m_target));
+        m_session.discardChanges();
+    } catch (sysrepo::Error& ex) {
         reportErrors();
     }
 }
 
 DatastoreAccess::Tree SysrepoAccess::execute(const std::string& path, const Tree& input)
 {
-    auto inputNode = treeToRpcInput(m_session->get_context(), path, input);
-    m_session->session_switch_ds(targetToDs_set(m_target));
-    auto output = m_session->rpc_send(inputNode);
-    return rpcOutputToTree(path, output);
+    auto inputNode = treeToRpcInput(m_session.getContext(), path, input);
+    m_session.switchDatastore(targetToDs_set(m_target));
+    auto output = m_session.sendRPC(inputNode);
+    return rpcOutputToTree(output);
 }
 
 void SysrepoAccess::copyConfig(const Datastore source, const Datastore destination)
 {
-    m_session->session_switch_ds(toSrDatastore(destination));
-    m_session->copy_config(toSrDatastore(source), nullptr, OPERATION_TIMEOUT_MS, 1);
+    m_session.switchDatastore(toSrDatastore(destination));
+    m_session.copyConfig(toSrDatastore(source), nullptr, OPERATION_TIMEOUT_MS);
 }
 
 std::shared_ptr<Schema> SysrepoAccess::schema()
@@ -240,16 +190,14 @@
 
 [[noreturn]] void SysrepoAccess::reportErrors() const
 {
-    // I only use get_error to get error info, since the error code from
-    // sysrepo_exception doesn't really give any meaningful information. For
-    // example an "invalid argument" error could mean a node isn't enabled, or
-    // it could mean something totally different and there is no documentation
-    // for that, so it's better to just use the message sysrepo gives me.
-    auto srErrors = m_session->get_error();
     std::vector<DatastoreError> res;
 
-    for (size_t i = 0; i < srErrors->error_cnt(); i++) {
-        res.emplace_back(srErrors->message(i), srErrors->xpath(i) ? std::optional<std::string>{srErrors->xpath(i)} : std::nullopt);
+    for (const auto& err : m_session.getErrors()) {
+        res.emplace_back(err.errorMessage);
+    }
+
+    for (const auto& err : m_session.getNetconfErrors()) {
+        res.emplace_back(err.message, err.path);
     }
 
     throw DatastoreException(res);
@@ -258,47 +206,23 @@
 std::vector<ListInstance> SysrepoAccess::listInstances(const std::string& path)
 {
     std::vector<ListInstance> res;
-    auto lists = getItems(path);
+    auto lists = m_session.getData(path.c_str());
+    if (!lists) {
+        return res;
+    }
 
-    decltype(lists) instances;
-    auto wantedTree = *(m_schema->dataNodeFromPath(path)->find_path(path.c_str())->data().begin());
-    std::copy_if(lists.begin(), lists.end(), std::inserter(instances, instances.end()), [this, pathToCheck = wantedTree->schema()->path()](const auto& item) {
-        // This filters out non-instances.
-        if (item.second.type() != typeid(special_) || boost::get<special_>(item.second).m_value != SpecialValue::List) {
-            return false;
-        }
-
-        // Now, getItems is recursive: it gives everything including nested lists. So I try create a tree from the instance...
-        auto instanceTree = *(m_schema->dataNodeFromPath(item.first)->find_path(item.first.c_str())->data().begin());
-        // And then check if its schema path matches the list we actually want. This filters out lists which are not the ones I requested.
-        return instanceTree->schema()->path() == pathToCheck;
-    });
-
-    // If there are no instances, then just return
+    auto instances = lists->findXPath(path.c_str());
     if (instances.empty()) {
         return res;
     }
 
-    // I need to find out which keys does the list have. To do that, I create a
-    // tree from the first instance. This is gives me some top level node,
-    // which will be our list in case out list is a top-level node. In case it
-    // isn't, we have call find_path on the top level node. After that, I just
-    // retrieve the keys.
-    auto topLevelTree = m_schema->dataNodeFromPath(instances.begin()->first);
-    auto list = *(topLevelTree->find_path(path.c_str())->data().begin());
-    auto keys = libyang::Schema_Node_List{list->schema()}.keys();
+    auto keys = instances.front().schema().asList().keys();
 
-    // Creating a full tree at the same time from the values sysrepo gives me
-    // would be a pain (and after sysrepo switches to libyang meaningless), so
-    // I just use this algorithm to create data nodes one by one and get the
-    // key values from them.
     for (const auto& instance : instances) {
-        auto wantedList = *(m_schema->dataNodeFromPath(instance.first)->find_path(path.c_str())->data().begin());
         ListInstance instanceRes;
         for (const auto& key : keys) {
-            auto vec = wantedList->find_path(key->name())->data();
-            auto leaf = std::make_shared<libyang::Data_Node_Leaf_List>(*(vec.begin()));
-            instanceRes.emplace(key->name(), leafValueFromNode(leaf));
+            auto leaf = instance.findPath(key.name().data());
+            instanceRes.emplace(std::string{leaf->schema().name()}, leafValueFromNode(leaf->asTerm()));
         }
         res.emplace_back(instanceRes);
     }
@@ -308,6 +232,11 @@
 
 std::string SysrepoAccess::dump(const DataFormat format) const
 {
-    auto root = m_session->get_data("/*");
-    return root->print_mem(format == DataFormat::Xml ? LYD_XML : LYD_JSON, LYP_WITHSIBLINGS | LYP_FORMAT);
+    auto root = m_session.getData("/*");
+    auto str = root->printStr(format == DataFormat::Xml ? libyang::DataFormat::XML : libyang::DataFormat::JSON, libyang::PrintFlags::WithSiblings);
+    if (!str) {
+        return "";
+    }
+
+    return std::string{*str};
 }
diff --git a/src/sysrepo_access.hpp b/src/sysrepo_access.hpp
index 7a02d8b..0f736d1 100644
--- a/src/sysrepo_access.hpp
+++ b/src/sysrepo_access.hpp
@@ -9,6 +9,7 @@
 #pragma once
 
 #include <string>
+#include <sysrepo-cpp/Connection.hpp>
 #include "datastore_access.hpp"
 
 /*! \class DatastoreAccess
@@ -47,7 +48,7 @@
     std::vector<ListInstance> listInstances(const std::string& path) override;
     [[noreturn]] void reportErrors() const;
 
-    std::shared_ptr<sysrepo::Connection> m_connection;
-    std::shared_ptr<sysrepo::Session> m_session;
+    sysrepo::Connection m_connection;
+    sysrepo::Session m_session;
     std::shared_ptr<YangSchema> m_schema;
 };
diff --git a/src/yang_access.cpp b/src/yang_access.cpp
index 0555616..72e38e7 100644
--- a/src/yang_access.cpp
+++ b/src/yang_access.cpp
@@ -2,8 +2,8 @@
 #include <experimental/iterator>
 #include <fstream>
 #include <iostream>
-#include <libyang/Tree_Data.hpp>
-#include <libyang/libyang.h>
+#include <libyang-cpp/DataNode.hpp>
+#include <libyang-cpp/Utils.hpp>
 #include "UniqueResource.hpp"
 #include "libyang_utils.hpp"
 #include "utils.hpp"
@@ -11,35 +11,21 @@
 #include "yang_schema.hpp"
 
 namespace {
-template <typename Type> using lyPtrDeleter_type = void (*)(Type*);
-template <typename Type> const lyPtrDeleter_type<Type> lyPtrDeleter;
-template <> const auto lyPtrDeleter<ly_set> = ly_set_free;
-template <> const auto lyPtrDeleter<ly_ctx> = static_cast<lyPtrDeleter_type<ly_ctx>>([] (auto* ptr) {ly_ctx_destroy(ptr, nullptr);});
-template <> const auto lyPtrDeleter<lyd_node> = lyd_free_withsiblings;
-
-template <typename Type>
-auto lyWrap(Type* ptr)
-{
-    return std::unique_ptr<Type, lyPtrDeleter_type<Type>>{ptr, lyPtrDeleter<Type>};
-}
-
 // Convenient for functions that take m_datastore as an argument
-using DatastoreType = std::unique_ptr<lyd_node, lyPtrDeleter_type<lyd_node>>;
+using DatastoreType = std::optional<libyang::DataNode>;
 }
 
 YangAccess::YangAccess()
-    : m_ctx(lyWrap(ly_ctx_new(nullptr, LY_CTX_DISABLE_SEARCHDIR_CWD)))
-    , m_datastore(lyWrap<lyd_node>(nullptr))
-    , m_schema(std::make_shared<YangSchema>(libyang::create_new_Context(m_ctx.get())))
-    , m_validation_mode(LYD_OPT_DATA)
+    : m_ctx(nullptr, libyang::ContextOptions::DisableSearchCwd)
+    , m_datastore(std::nullopt)
+    , m_schema(std::make_shared<YangSchema>(m_ctx))
 {
 }
 
 YangAccess::YangAccess(std::shared_ptr<YangSchema> schema)
-    : m_ctx(schema->m_context->swig_ctx(), [](auto) {})
-    , m_datastore(lyWrap<lyd_node>(nullptr))
+    : m_ctx(schema->m_context)
+    , m_datastore(std::nullopt)
     , m_schema(schema)
-    , m_validation_mode(LYD_OPT_RPC)
 {
 }
 
@@ -47,78 +33,69 @@
 
 [[noreturn]] void YangAccess::getErrorsAndThrow() const
 {
-    auto errors = libyang::get_ly_errors(libyang::create_new_Context(m_ctx.get()));
     std::vector<DatastoreError> errorsRes;
-    for (const auto& error : errors) {
-        using namespace std::string_view_literals;
-        errorsRes.emplace_back(error->errmsg(), error->errpath() != ""sv ? std::optional{error->errpath()} : std::nullopt);
-    }
 
+    for (const auto& err : m_ctx.getErrors()) {
+        errorsRes.emplace_back(err.message, err.path);
+    }
     throw DatastoreException(errorsRes);
 }
 
 void YangAccess::impl_newPath(const std::string& path, const std::optional<std::string>& value)
 {
-    auto newNode = lyd_new_path(m_datastore.get(), m_ctx.get(), path.c_str(), value ? (void*)value->c_str() : nullptr, LYD_ANYDATA_CONSTSTRING, LYD_PATH_OPT_UPDATE);
-    if (!newNode) {
+    try {
+        if (m_datastore) {
+            m_datastore->newPath(path.c_str(), value ? value->c_str() : nullptr, libyang::CreationOptions::Update);
+        } else {
+            m_datastore = m_ctx.newPath(path.c_str(), value ? value->c_str() : nullptr, libyang::CreationOptions::Update);
+        }
+    } catch (libyang::Error&) {
         getErrorsAndThrow();
     }
-    if (!m_datastore) {
-        m_datastore = lyWrap(newNode);
-    }
 }
 
 namespace {
-void impl_unlink(DatastoreType& datastore, lyd_node* what)
+void impl_unlink(DatastoreType& datastore, libyang::DataNode what)
 {
     // If the node to be unlinked is the one our datastore variable points to, we need to find a new one to point to (one of its siblings)
-    if (datastore.get() == what) {
-        auto oldDatastore = datastore.release();
-        if (oldDatastore->prev != oldDatastore) {
-            datastore = lyWrap(oldDatastore->prev);
-        } else {
-            datastore = lyWrap(oldDatastore->next);
-        }
+
+    if (datastore == what) {
+        auto oldDatastore = datastore;
+        do {
+            datastore = datastore->previousSibling();
+            if (datastore == oldDatastore) {
+                // We have gone all the way back to our original node, which means it's the only node in our
+                // datastore.
+                datastore = std::nullopt;
+                break;
+            }
+        } while (datastore->schema().module().name() == "ietf-yang-library");
     }
 
-    lyd_unlink(what);
+    what.unlink();
 }
 }
 
 void YangAccess::impl_removeNode(const std::string& path)
 {
-    auto set = lyWrap(lyd_find_path(m_datastore.get(), path.c_str()));
-    if (!set || set->number == 0) {
-        // Check if schema node exists - lyd_find_path first checks if the first argument is non-null before checking for path validity
-        if (!ly_ctx_get_node(m_ctx.get(), nullptr, path.c_str(), 0)) {
-            throw DatastoreException{{DatastoreError{"Schema node doesn't exist.", path}}};
-        }
-        // Check if libyang found another error
-        if (ly_err_first(m_ctx.get())) {
-            getErrorsAndThrow();
-        }
-
+    if (!m_datastore) {
+        // Otherwise the datastore just doesn't contain the wanted node.
+        throw DatastoreException{{DatastoreError{"Datastore is empty.", path}}};
+    }
+    auto toRemove = m_datastore->findPath(path.c_str());
+    if (!toRemove) {
         // Otherwise the datastore just doesn't contain the wanted node.
         throw DatastoreException{{DatastoreError{"Data node doesn't exist.", path}}};
     }
 
-    auto toRemove = set->set.d[0];
-
-    impl_unlink(m_datastore, toRemove);
-
-    lyd_free(toRemove);
+    impl_unlink(m_datastore, *toRemove);
 }
 
 void YangAccess::validate()
 {
-    auto datastore = m_datastore.release();
-
-    if (m_validation_mode == LYD_OPT_RPC) {
-        lyd_validate(&datastore, m_validation_mode, nullptr);
-    } else {
-        lyd_validate(&datastore, m_validation_mode | LYD_OPT_DATA_NO_YANGLIB, m_ctx.get());
+    if (m_datastore) {
+        libyang::validateAll(m_datastore);
     }
-    m_datastore = lyWrap(datastore);
 }
 
 DatastoreAccess::Tree YangAccess::getItems(const std::string& path) const
@@ -128,10 +105,9 @@
         return res;
     }
 
-    auto set = lyWrap(lyd_find_path(m_datastore.get(), path == "/" ? "/*" : path.c_str()));
-    auto setWrapper = libyang::Set(set.get(), nullptr);
-    std::optional<std::string> ignoredXPathPrefix;
-    lyNodesToTree(res, setWrapper.data());
+    auto set = m_datastore->findXPath(path == "/" ? "/*" : path.c_str());
+
+    lyNodesToTree(res, set);
     return res;
 }
 
@@ -154,66 +130,60 @@
 namespace {
 struct impl_moveItem {
     DatastoreType& m_datastore;
-    lyd_node* m_sourceNode;
+    libyang::DataNode m_sourceNode;
 
     void operator()(yang::move::Absolute absolute) const
     {
-        auto set = lyWrap(lyd_find_instance(m_sourceNode, m_sourceNode->schema));
-        if (set->number == 1) { // m_sourceNode is the sole instance, do nothing
+        auto set = m_sourceNode.findXPath(m_sourceNode.schema().path().get().get());
+        if (set.size() == 1) { // m_sourceNode is the sole instance, do nothing
             return;
         }
 
-        doUnlink();
         switch (absolute) {
         case yang::move::Absolute::Begin:
-            if (set->set.d[0] == m_sourceNode) { // List is already at the beginning, do nothing
+            if (set.front() == m_sourceNode) { // List is already at the beginning, do nothing
                 return;
             }
-            lyd_insert_before(set->set.d[0], m_sourceNode);
-            return;
+            set.front().insertBefore(m_sourceNode);
+            break;
         case yang::move::Absolute::End:
-            if (set->set.d[set->number - 1] == m_sourceNode) { // List is already at the end, do nothing
+            if (set.back() == m_sourceNode) { // List is already at the end, do nothing
                 return;
             }
-            lyd_insert_after(set->set.d[set->number - 1], m_sourceNode);
-            return;
+            set.back().insertAfter(m_sourceNode);
+            break;
         }
+        m_datastore = m_datastore->firstSibling();
     }
 
     void operator()(const yang::move::Relative& relative) const
     {
-        auto keySuffix = m_sourceNode->schema->nodetype == LYS_LIST ? instanceToString(relative.m_path)
+        auto keySuffix = m_sourceNode.schema().nodeType() == libyang::NodeType::List ? instanceToString(relative.m_path)
                                                                     : leafDataToString(relative.m_path.at("."));
-        lyd_node* destNode;
-        lyd_find_sibling_val(m_sourceNode, m_sourceNode->schema, keySuffix.c_str(), &destNode);
+        auto destNode = m_sourceNode.findSiblingVal(m_sourceNode.schema(), keySuffix.c_str());
 
-        doUnlink();
         if (relative.m_position == yang::move::Relative::Position::After) {
-            lyd_insert_after(destNode, m_sourceNode);
+            destNode->insertAfter(m_sourceNode);
         } else {
-            lyd_insert_before(destNode, m_sourceNode);
+            destNode->insertBefore(m_sourceNode);
         }
     }
-
-private:
-    void doUnlink() const
-    {
-        impl_unlink(m_datastore, m_sourceNode);
-    }
 };
 }
 
 void YangAccess::moveItem(const std::string& source, std::variant<yang::move::Absolute, yang::move::Relative> move)
 {
-    auto set = lyWrap(lyd_find_path(m_datastore.get(), source.c_str()));
-    if (!set) { // Error, the node probably doesn't exist in the schema
-        getErrorsAndThrow();
+    if (!m_datastore) {
+        throw DatastoreException{{DatastoreError{"Datastore is empty.", source}}};
     }
-    if (set->number == 0) {
-        return;
+
+    auto sourceNode = m_datastore->findPath(source.c_str());
+
+    if (!sourceNode) {
+        // The datastore doesn't contain the wanted node.
+        throw DatastoreException{{DatastoreError{"Data node doesn't exist.", source}}};
     }
-    auto sourceNode = set->set.d[0];
-    std::visit(impl_moveItem{m_datastore, sourceNode}, move);
+    std::visit(impl_moveItem{m_datastore, *sourceNode}, move);
 }
 
 void YangAccess::commitChanges()
@@ -227,16 +197,24 @@
 
 [[noreturn]] DatastoreAccess::Tree YangAccess::execute(const std::string& path, const Tree& input)
 {
-    auto root = lyWrap(lyd_new_path(nullptr, m_ctx.get(), path.c_str(), nullptr, LYD_ANYDATA_CONSTSTRING, 0));
-    if (!root) {
-        getErrorsAndThrow();
-    }
+    auto root = [&path, this]  {
+        try {
+            return m_ctx.newPath(path.c_str());
+        } catch (libyang::ErrorWithCode& err) {
+            getErrorsAndThrow();
+        }
+    }();
+
     for (const auto& [k, v] : input) {
         if (v.type() == typeid(special_) && boost::get<special_>(v).m_value != SpecialValue::PresenceContainer) {
             continue;
         }
 
-        lyd_new_path(root.get(), m_ctx.get(), k.c_str(), (void*)leafDataToString(v).c_str(), LYD_ANYDATA_CONSTSTRING, LYD_PATH_OPT_UPDATE);
+        try {
+            root.newPath(k.c_str(), leafDataToString(v).c_str(), libyang::CreationOptions::Update);
+        } catch (libyang::ErrorWithCode& err) {
+            getErrorsAndThrow();
+        }
     }
     throw std::logic_error("in-memory datastore doesn't support executing RPC/action");
 }
@@ -244,7 +222,7 @@
 void YangAccess::copyConfig(const Datastore source, const Datastore dest)
 {
     if (source == Datastore::Startup && dest == Datastore::Running) {
-        m_datastore = nullptr;
+        m_datastore = std::nullopt;
     }
 }
 
@@ -260,16 +238,14 @@
         return res;
     }
 
-    auto instances = lyWrap(lyd_find_path(m_datastore.get(), path.c_str()));
-    auto instancesWrapper = libyang::Set(instances.get(), nullptr);
-    for (const auto& list : instancesWrapper.data()) {
+    auto instances = m_datastore->findXPath(path.c_str());
+    for (const auto& list : instances) {
         ListInstance instance;
-        for (const auto& child : list->child()->tree_for()) {
-            if (child->schema()->nodetype() == LYS_LEAF) {
-                libyang::Schema_Node_Leaf leafSchema(child->schema());
-                if (leafSchema.is_key()) {
-                    auto leafData = std::make_shared<libyang::Data_Node_Leaf_List>(child);
-                    instance.insert({leafSchema.name(), leafValueFromNode(leafData)});
+        for (const auto& child : list.child()->siblings()) {
+            if (child.schema().nodeType() == libyang::NodeType::Leaf) {
+                auto leafSchema(child.schema().asLeaf());
+                if (leafSchema.isKey()) {
+                    instance.insert({std::string{leafSchema.name()}, leafValueFromNode(child.asTerm())});
                 }
             }
         }
@@ -280,16 +256,16 @@
 
 std::string YangAccess::dump(const DataFormat format) const
 {
-    char* output;
-    lyd_print_mem(&output, m_datastore.get(), format == DataFormat::Xml ? LYD_XML : LYD_JSON, LYP_WITHSIBLINGS | LYP_FORMAT);
-    std::unique_ptr<char, decltype(&free)> deleter{output, free};
-
-    if (output) {
-        std::string res = output;
-        return res;
+    if (!m_datastore) {
+        return "";
     }
 
-    return "";
+    auto str = m_datastore->firstSibling().printStr(format == DataFormat::Xml ? libyang::DataFormat::XML : libyang::DataFormat::JSON, libyang::PrintFlags::WithSiblings);
+    if (!str) {
+        return "";
+    }
+
+    return std::string{*str};
 }
 
 void YangAccess::loadModule(const std::string& name)
@@ -307,9 +283,9 @@
     m_schema->addSchemaDirectory(path.c_str());
 }
 
-void YangAccess::enableFeature(const std::string& module, const std::string& feature)
+void YangAccess::setEnabledFeatures(const std::string& module, const std::vector<std::string>& features)
 {
-    m_schema->enableFeature(module, feature);
+    m_schema->setEnabledFeatures(module, features);
 }
 
 void YangAccess::addDataFile(const std::string& path, const StrictDataParsing strict)
@@ -320,20 +296,16 @@
 
     std::cout << "Parsing \"" << path << "\" as " << (firstChar == '{' ? "JSON" : "XML") << "...\n";
 
-    auto parseFlags = LYD_OPT_DATA | LYD_OPT_DATA_NO_YANGLIB | LYD_OPT_TRUSTED;
-    if (strict == StrictDataParsing::Yes) {
-        parseFlags |= LYD_OPT_STRICT;
-    }
-    auto dataNode = lyd_parse_path(m_ctx.get(), path.c_str(), firstChar == '{' ? LYD_JSON : LYD_XML, parseFlags);
-
-    if (!dataNode) {
-        throw std::runtime_error("Supplied data file " + path + " couldn't be parsed.");
-    }
+    auto dataNode = m_ctx.parseDataPath(
+            path.c_str(),
+            firstChar == '{' ? libyang::DataFormat::JSON : libyang::DataFormat::XML,
+            strict == StrictDataParsing::Yes ? std::optional{libyang::ParseOptions::Strict} : std::nullopt,
+            libyang::ValidationOptions::Present);
 
     if (!m_datastore) {
-        m_datastore = lyWrap(dataNode);
+        m_datastore = dataNode;
     } else {
-        lyd_merge(m_datastore.get(), dataNode, LYD_OPT_DESTRUCT);
+        m_datastore->merge(*dataNode);
     }
 
     validate();
diff --git a/src/yang_access.hpp b/src/yang_access.hpp
index 64538f0..aab5d81 100644
--- a/src/yang_access.hpp
+++ b/src/yang_access.hpp
@@ -7,6 +7,7 @@
 
 #pragma once
 
+#include <libyang-cpp/Context.hpp>
 #include "datastore_access.hpp"
 
 /*! \class YangAccess
@@ -40,7 +41,7 @@
 
     std::shared_ptr<Schema> schema() override;
 
-    void enableFeature(const std::string& module, const std::string& feature);
+    void setEnabledFeatures(const std::string& module, const std::vector<std::string>& features);
     [[nodiscard]] std::string dump(const DataFormat format) const override;
 
     void loadModule(const std::string& name);
@@ -57,8 +58,7 @@
     void impl_removeNode(const std::string& path);
     void validate();
 
-    std::unique_ptr<ly_ctx, void (*)(ly_ctx*)> m_ctx;
-    std::unique_ptr<lyd_node, void (*)(lyd_node*)> m_datastore;
+    libyang::Context m_ctx;
+    std::optional<libyang::DataNode> m_datastore;
     std::shared_ptr<YangSchema> m_schema;
-    const int m_validation_mode;
 };
diff --git a/src/yang_schema.cpp b/src/yang_schema.cpp
index b964d31..f96aa46 100644
--- a/src/yang_schema.cpp
+++ b/src/yang_schema.cpp
@@ -6,9 +6,8 @@
  *
 */
 
-#include <libyang/Libyang.hpp>
-#include <libyang/Tree_Data.hpp>
-#include <libyang/Tree_Schema.hpp>
+#include <libyang-cpp/Enum.hpp>
+#include <libyang-cpp/Utils.hpp>
 #include <string_view>
 #include "UniqueResource.hpp"
 #include "utils.hpp"
@@ -33,11 +32,11 @@
 };
 
 YangSchema::YangSchema()
-    : m_context(std::make_shared<libyang::Context>(nullptr, LY_CTX_DISABLE_SEARCHDIR_CWD))
+    : m_context(nullptr, libyang::ContextOptions::DisableSearchDirs | libyang::ContextOptions::SetPrivParsed)
 {
 }
 
-YangSchema::YangSchema(std::shared_ptr<libyang::Context> lyCtx)
+YangSchema::YangSchema(libyang::Context lyCtx)
     : m_context(lyCtx)
 {
 }
@@ -46,29 +45,22 @@
 
 void YangSchema::addSchemaString(const char* schema)
 {
-    if (!m_context->parse_module_mem(schema, LYS_IN_YANG)) {
-        throw YangLoadError("Couldn't load schema");
-    }
+    m_context.parseModuleMem(schema, libyang::SchemaFormat::YANG);
 }
 
 void YangSchema::addSchemaDirectory(const char* directoryName)
 {
-    if (m_context->set_searchdir(directoryName)) {
-        throw YangLoadError("Couldn't add schema search directory");
-    }
+    m_context.setSearchDir(directoryName);
 }
 
 void YangSchema::addSchemaFile(const char* filename)
 {
-    if (!m_context->parse_module_path(filename, LYS_IN_YANG)) {
-        throw YangLoadError("Couldn't load schema");
-    }
+    m_context.parseModulePath(filename, libyang::SchemaFormat::YANG);
 }
 
 bool YangSchema::isModule(const std::string& name) const
 {
-    const auto set = modules();
-    return set.find(name) != set.end();
+    return m_context.getModuleImplemented(name.c_str()).has_value();
 }
 
 bool YangSchema::listHasKey(const schemaPath_& listPath, const std::string& key) const
@@ -80,49 +72,52 @@
 bool YangSchema::leafIsKey(const std::string& leafPath) const
 {
     auto node = getSchemaNode(leafPath);
-    if (!node || node->nodetype() != LYS_LEAF) {
+    if (!node || node->nodeType() != libyang::NodeType::Leaf) {
         return false;
     }
 
-    return libyang::Schema_Node_Leaf{node}.is_key().get();
+    return node->asLeaf().isKey();
 }
 
-libyang::S_Schema_Node YangSchema::impl_getSchemaNode(const std::string& node) const
+std::optional<libyang::SchemaNode> YangSchema::impl_getSchemaNode(const std::string& node) const
 {
-    // If no node is found find_path prints an error message, so we have to
-    // disable logging
-    // https://github.com/CESNET/libyang/issues/753
-    {
-        int oldOptions;
-        auto logBlocker = make_unique_resource(
-            [&oldOptions]() {
-                oldOptions = libyang::set_log_options(0);
-            },
-            [&oldOptions]() {
-                libyang::set_log_options(oldOptions);
-            });
-        auto res = m_context->get_node(nullptr, node.c_str());
-        if (!res) { // If no node is found, try output rpc nodes too.
-            res = m_context->get_node(nullptr, node.c_str(), 1);
+    // libyang::Context::findPath throws an exception, when no matching schema node is found. This exception has the
+    // ValidationFailure error code. We will catch that exception (and rethrow if it's not the correct error code.
+    //
+    // Also, we need to use findPath twice if we're trying to find output nodes.
+    try {
+        return m_context.findPath(node.c_str());
+    } catch (libyang::ErrorWithCode& err) {
+        if (err.code() != libyang::ErrorCode::ValidationFailure) {
+            throw;
         }
-        return res;
     }
+    try {
+        return m_context.findPath(node.c_str(), libyang::OutputNodes::Yes);
+    } catch (libyang::ErrorWithCode& err) {
+        if (err.code() != libyang::ErrorCode::ValidationFailure) {
+            throw;
+        }
+    }
+
+    // We didn't find a matching node.
+    return std::nullopt;
 }
 
 
-libyang::S_Schema_Node YangSchema::getSchemaNode(const std::string& node) const
+std::optional<libyang::SchemaNode> YangSchema::getSchemaNode(const std::string& node) const
 {
     return impl_getSchemaNode(node);
 }
 
-libyang::S_Schema_Node YangSchema::getSchemaNode(const schemaPath_& location, const ModuleNodePair& node) const
+std::optional<libyang::SchemaNode> YangSchema::getSchemaNode(const schemaPath_& location, const ModuleNodePair& node) const
 {
     std::string absPath = joinPaths(pathToSchemaString(location, Prefixes::Always), fullNodeName(location, node));
 
     return impl_getSchemaNode(absPath);
 }
 
-libyang::S_Schema_Node YangSchema::getSchemaNode(const schemaPath_& listPath) const
+std::optional<libyang::SchemaNode> YangSchema::getSchemaNode(const schemaPath_& listPath) const
 {
     std::string absPath = pathToSchemaString(listPath, Prefixes::Always);
     return impl_getSchemaNode(absPath);
@@ -131,174 +126,121 @@
 const std::set<std::string> YangSchema::listKeys(const schemaPath_& listPath) const
 {
     auto node = getSchemaNode(listPath);
-    if (node->nodetype() != LYS_LIST) {
+    if (node->nodeType() != libyang::NodeType::List) {
         return {};
     }
 
-    auto list = std::make_shared<libyang::Schema_Node_List>(node);
     std::set<std::string> keys;
-    const auto& keysVec = list->keys();
+    auto keysVec = node->asList().keys();
 
-    std::transform(keysVec.begin(), keysVec.end(), std::inserter(keys, keys.begin()), [](const auto& it) { return it->name(); });
+    std::transform(keysVec.begin(), keysVec.end(), std::inserter(keys, keys.begin()), [](const auto& it) { return std::string{it.name()}; });
     return keys;
 }
 
-namespace {
-enum class ResolveMode {
-    Enum,
-    Identity
-};
-/** @brief Resolves a typedef to a type which defines values.
- * When we need allowed values of a type and that type is a typedef, we need to recurse into the typedef until we find a
- * type which defines values. These values are the allowed values.
- * Example:
- *
- * typedef MyOtherEnum {
- *   type enumeration {
- *     enum "A";
- *     enum "B";
- *   }
- * }
- *
- * typedef MyEnum {
- *   type MyOtherEnum;
- * }
- *
- * If `toResolve` points to MyEnum, then just doing ->enums()->enm() returns nothing and that means that this particular
- * typedef (MyEnum) did not say which values are allowed. So, we need to dive into the parent enum (MyOtherEnum) with
- * ->der()->type(). This typedef (MyOtherEnum) DID specify allowed values and enums()->enm() WILL contain them. These
- *  values are the only relevant values and we don't care about other parent typedefs. We return these values to the
- *  caller.
- *
- *  For enums, this function simply returns all allowed enums.
- *  For identities, this function returns which bases `toResolve` has.
- */
-template <ResolveMode TYPE>
-auto resolveTypedef(const libyang::S_Type& toResolve)
+std::set<enum_> enumValues(const libyang::Type& type)
 {
-    auto type = toResolve;
-    auto getValuesFromType = [] (const libyang::S_Type& type) {
-        if constexpr (TYPE == ResolveMode::Identity) {
-            return type->info()->ident()->ref();
-        } else {
-            return type->info()->enums()->enm();
-        }
-    };
-    auto values = getValuesFromType(type);
-    while (values.empty()) {
-        type = type->der()->type();
-        values = getValuesFromType(type);
-    }
-
-    return values;
-}
-
-std::set<enum_> enumValues(const libyang::S_Type& type)
-{
-    auto values = resolveTypedef<ResolveMode::Enum>(type);
-
-    std::vector<libyang::S_Type_Enum> enabled;
-    std::copy_if(values.begin(), values.end(), std::back_inserter(enabled), [](const libyang::S_Type_Enum& it) {
-        auto iffeatures = it->iffeature();
-        return std::all_of(iffeatures.begin(), iffeatures.end(), [](auto it) { return it->value(); });
-    });
-
+    auto enums = type.asEnum().items();
     std::set<enum_> enumSet;
-    std::transform(enabled.begin(), enabled.end(), std::inserter(enumSet, enumSet.end()), [](auto it) { return enum_{it->name()}; });
+    std::transform(enums.begin(), enums.end(), std::inserter(enumSet, enumSet.end()), [](auto it) { return enum_{std::string{it.name}}; });
     return enumSet;
 }
 
-std::set<identityRef_> validIdentities(const libyang::S_Type& type)
+std::set<identityRef_> validIdentities(const libyang::Type& type)
 {
     std::set<identityRef_> identSet;
 
-    for (auto base : resolveTypedef<ResolveMode::Identity>(type)) { // Iterate over all bases
-        // Iterate over derived identities (this is recursive!)
-        if (auto der = base->der()) {
-            for (auto derived : der->schema()) {
-                identSet.emplace(derived->module()->name(), derived->name());
-            }
+    std::function<void(const std::vector<libyang::Identity>&)> impl = [&identSet, &impl] (const std::vector<libyang::Identity>& idents) {
+        if (idents.empty()) {
+            return;
         }
+
+        for (const auto& ident : idents) {
+            identSet.emplace(std::string{ident.module().name()}, std::string{ident.name()});
+            impl(ident.derived());
+        }
+    };
+
+    for (const auto& base : type.asIdentityRef().bases()) {
+        impl(base.derived());
     }
 
     return identSet;
 }
 
-std::string leafrefPath(const libyang::S_Type& type)
+std::string leafrefPath(const libyang::Type& type)
 {
-    return type->info()->lref()->target()->path(LYS_PATH_FIRST_PREFIX);
-}
+    return std::string{type.asLeafRef().path()};
 }
 
 template <typename NodeType>
-yang::TypeInfo YangSchema::impl_leafType(const libyang::S_Schema_Node& node) const
+yang::TypeInfo YangSchema::impl_leafType(const NodeType& node) const
 {
     using namespace std::string_literals;
     auto leaf = std::make_shared<NodeType>(node);
     auto leafUnits = leaf->units();
-    std::function<yang::TypeInfo(std::shared_ptr<libyang::Type>)> resolveType;
-    resolveType = [this, &resolveType, leaf, leafUnits](std::shared_ptr<libyang::Type> type) -> yang::TypeInfo {
+    std::function<yang::TypeInfo(const libyang::Type&)> resolveType;
+    resolveType = [&resolveType, leaf, leafUnits](const libyang::Type& type) -> yang::TypeInfo {
         yang::LeafDataType resType;
-        switch (type->base()) {
-        case LY_TYPE_STRING:
+        switch (type.base()) {
+        case libyang::LeafBaseType::String:
             resType.emplace<yang::String>();
             break;
-        case LY_TYPE_DEC64:
+        case libyang::LeafBaseType::Dec64:
             resType.emplace<yang::Decimal>();
             break;
-        case LY_TYPE_BOOL:
+        case libyang::LeafBaseType::Bool:
             resType.emplace<yang::Bool>();
             break;
-        case LY_TYPE_INT8:
+        case libyang::LeafBaseType::Int8:
             resType.emplace<yang::Int8>();
             break;
-        case LY_TYPE_INT16:
+        case libyang::LeafBaseType::Int16:
             resType.emplace<yang::Int16>();
             break;
-        case LY_TYPE_INT32:
+        case libyang::LeafBaseType::Int32:
             resType.emplace<yang::Int32>();
             break;
-        case LY_TYPE_INT64:
+        case libyang::LeafBaseType::Int64:
             resType.emplace<yang::Int64>();
             break;
-        case LY_TYPE_UINT8:
+        case libyang::LeafBaseType::Uint8:
             resType.emplace<yang::Uint8>();
             break;
-        case LY_TYPE_UINT16:
+        case libyang::LeafBaseType::Uint16:
             resType.emplace<yang::Uint16>();
             break;
-        case LY_TYPE_UINT32:
+        case libyang::LeafBaseType::Uint32:
             resType.emplace<yang::Uint32>();
             break;
-        case LY_TYPE_UINT64:
+        case libyang::LeafBaseType::Uint64:
             resType.emplace<yang::Uint64>();
             break;
-        case LY_TYPE_BINARY:
+        case libyang::LeafBaseType::Binary:
             resType.emplace<yang::Binary>();
             break;
-        case LY_TYPE_EMPTY:
+        case libyang::LeafBaseType::Empty:
             resType.emplace<yang::Empty>();
             break;
-        case LY_TYPE_ENUM:
+        case libyang::LeafBaseType::Enum:
             resType.emplace<yang::Enum>(enumValues(type));
             break;
-        case LY_TYPE_IDENT:
+        case libyang::LeafBaseType::IdentityRef:
             resType.emplace<yang::IdentityRef>(validIdentities(type));
             break;
-        case LY_TYPE_LEAFREF:
-            resType.emplace<yang::LeafRef>(::leafrefPath(type), std::make_unique<yang::TypeInfo>(leafType(::leafrefPath(type))));
+        case libyang::LeafBaseType::Leafref:
+            resType.emplace<yang::LeafRef>(::leafrefPath(type), std::make_unique<yang::TypeInfo>(resolveType(type.asLeafRef().resolvedType())));
             break;
-        case LY_TYPE_BITS: {
+        case libyang::LeafBaseType::Bits: {
             auto resBits = yang::Bits{};
-            for (const auto& bit : type->info()->bits()->bit()) {
-                resBits.m_allowedValues.emplace(bit->name());
+            for (const auto& bit : type.asBits().items()) {
+                resBits.m_allowedValues.emplace(std::string{bit.name});
             }
             resType.emplace<yang::Bits>(std::move(resBits));
             break;
         }
-        case LY_TYPE_UNION: {
+        case libyang::LeafBaseType::Union: {
             auto resUnion = yang::Union{};
-            for (auto unionType : type->info()->uni()->types()) {
+            for (auto unionType : type.asUnion().types()) {
                 resUnion.m_unionTypes.emplace_back(resolveType(unionType));
             }
             resType.emplace<yang::Union>(std::move(resUnion));
@@ -306,48 +248,26 @@
         }
         default:
             using namespace std::string_literals;
-            throw UnsupportedYangTypeException("the type of "s + leaf->name() + " is not supported: " + std::to_string(leaf->type()->base()));
+            throw UnsupportedYangTypeException("the type of "s +
+                    std::string{leaf->name()} +
+                    " is not supported: " +
+                    std::to_string(std::underlying_type_t<libyang::LeafBaseType>(leaf->valueType().base())));
         }
 
-        std::optional<std::string> resUnits;
 
-        if (leafUnits) {
-            resUnits = leafUnits;
-        } else {
-            for (auto parentTypedef = type->der(); parentTypedef; parentTypedef = parentTypedef->type()->der()) {
-                auto units = parentTypedef->units();
-                if (units) {
-                    resUnits = units;
-                    break;
-                }
-            }
-        }
-
-        std::optional<std::string> resDescription;
-
-        // checking for parentTypedef->type()->der() means I'm going to enter inside base types like "string". These
-        // also have a description, but it isn't too helpful ("human-readable string")
-        for (auto parentTypedef = type->der(); parentTypedef && parentTypedef->type()->der(); parentTypedef = parentTypedef->type()->der()) {
-            auto dsc = parentTypedef->dsc();
-            if (dsc) {
-                resDescription = dsc;
-                break;
-            }
-        }
-
-        return yang::TypeInfo(resType, resUnits, resDescription);
+        return yang::TypeInfo(resType, std::optional<std::string>{leafUnits}, std::optional<std::string>{type.description()});
     };
-    return resolveType(leaf->type());
+    return resolveType(leaf->valueType());
 }
 
 yang::TypeInfo YangSchema::leafType(const schemaPath_& location, const ModuleNodePair& node) const
 {
     auto lyNode = getSchemaNode(location, node);
-    switch (lyNode->nodetype()) {
-    case LYS_LEAF:
-        return impl_leafType<libyang::Schema_Node_Leaf>(lyNode);
-    case LYS_LEAFLIST:
-        return impl_leafType<libyang::Schema_Node_Leaflist>(lyNode);
+    switch (lyNode->nodeType()) {
+    case libyang::NodeType::Leaf:
+        return impl_leafType(lyNode->asLeaf());
+    case libyang::NodeType::Leaflist:
+        return impl_leafType(lyNode->asLeafList());
     default:
         throw std::logic_error("YangSchema::leafType: type must be leaf or leaflist");
     }
@@ -356,11 +276,11 @@
 yang::TypeInfo YangSchema::leafType(const std::string& path) const
 {
     auto lyNode = getSchemaNode(path);
-    switch (lyNode->nodetype()) {
-    case LYS_LEAF:
-        return impl_leafType<libyang::Schema_Node_Leaf>(lyNode);
-    case LYS_LEAFLIST:
-        return impl_leafType<libyang::Schema_Node_Leaflist>(lyNode);
+    switch (lyNode->nodeType()) {
+    case libyang::NodeType::Leaf:
+        return impl_leafType(lyNode->asLeaf());
+    case libyang::NodeType::Leaflist:
+        return impl_leafType(lyNode->asLeafList());
     default:
         throw std::logic_error("YangSchema::leafType: type must be leaf or leaflist");
     }
@@ -368,23 +288,22 @@
 
 std::optional<std::string> YangSchema::leafTypeName(const std::string& path) const
 {
-    libyang::Schema_Node_Leaf leaf(getSchemaNode(path));
-    return leaf.type()->der().get() && leaf.type()->der()->type()->der().get() ? std::optional{leaf.type()->der()->name()} : std::nullopt;
+    auto leaf = getSchemaNode(path)->asLeaf();
+    return std::string{leaf.valueType().name()};
 }
 
 std::string YangSchema::leafrefPath(const std::string& leafrefPath) const
 {
     using namespace std::string_literals;
-    libyang::Schema_Node_Leaf leaf(getSchemaNode(leafrefPath));
-    return leaf.type()->info()->lref()->target()->path(LYS_PATH_FIRST_PREFIX);
+    return ::leafrefPath(getSchemaNode(leafrefPath)->asLeaf().valueType());
 }
 
 std::set<std::string> YangSchema::modules() const
 {
-    const auto& modules = m_context->get_module_iter();
+    const auto& modules = m_context.modules();
 
     std::set<std::string> res;
-    std::transform(modules.begin(), modules.end(), std::inserter(res, res.end()), [](const auto module) { return module->name(); });
+    std::transform(modules.begin(), modules.end(), std::inserter(res, res.end()), [](const auto module) { return std::string{module.name()}; });
     return res;
 }
 
@@ -392,39 +311,49 @@
 {
     using namespace std::string_view_literals;
     std::set<ModuleNodePair> res;
-    std::vector<libyang::S_Schema_Node> nodes;
+    std::vector<libyang::ChildInstanstiables> nodeCollections;
     std::string topLevelModule;
 
     if (path.type() == typeid(module_)) {
-        nodes = m_context->get_module(boost::get<module_>(path).m_name.c_str())->data_instantiables(0);
+        nodeCollections.emplace_back(m_context.getModule(boost::get<module_>(path).m_name.c_str())->childInstantiables());
     } else {
         auto schemaPath = anyPathToSchemaPath(path);
         if (schemaPath.m_nodes.empty()) {
-            nodes = m_context->data_instantiables(0);
+            for (const auto& module : m_context.modules()) {
+                if (module.implemented()) {
+                    nodeCollections.emplace_back(module.childInstantiables());
+                }
+            }
         } else {
             const auto pathString = pathToSchemaString(schemaPath, Prefixes::Always);
             const auto node = getSchemaNode(pathString);
-            nodes = node->child_instantiables(0);
+            nodeCollections.emplace_back(node->childInstantiables());
             topLevelModule = schemaPath.m_nodes.begin()->m_prefix->m_name;
         }
     }
 
-    for (const auto& node : nodes) {
-        if (node->module()->name() == "ietf-yang-library"sv) {
-            continue;
-        }
+    for (const auto& coll : nodeCollections) {
+        for (const auto& node : coll) {
+            if (node.module().name() == "ietf-yang-library"sv) {
+                continue;
+            }
 
-        if (recursion == Recursion::Recursive) {
-            for (auto it : node->tree_dfs()) {
-                res.insert(ModuleNodePair(boost::none, it->path(LYS_PATH_FIRST_PREFIX)));
+            if (node.module().name() == "ietf-yang-schema-mount"sv) {
+                continue;
             }
-        } else {
-            ModuleNodePair toInsert;
-            if (topLevelModule.empty() || topLevelModule != node->module()->name()) {
-                toInsert.first = node->module()->type() == 0 ? node->module()->name() : libyang::Submodule(node->module()).belongsto()->name();
+
+            if (recursion == Recursion::Recursive) {
+                for (auto it : node.childrenDfs()) {
+                    res.insert(ModuleNodePair(boost::none, it.path()));
+                }
+            } else {
+                ModuleNodePair toInsert;
+                if (topLevelModule.empty() || topLevelModule != node.module().name()) {
+                    toInsert.first = std::string{node.module().name()};
+                }
+                toInsert.second = node.name();
+                res.insert(toInsert);
             }
-            toInsert.second = node->name();
-            res.insert(toInsert);
         }
     }
 
@@ -433,71 +362,81 @@
 
 void YangSchema::loadModule(const std::string& moduleName)
 {
-    m_context->load_module(moduleName.c_str());
+    m_context.loadModule(moduleName.c_str());
 }
 
-void YangSchema::enableFeature(const std::string& moduleName, const std::string& featureName)
+void YangSchema::setEnabledFeatures(const std::string& moduleName, const std::vector<std::string>& features)
 {
     using namespace std::string_literals;
     auto module = getYangModule(moduleName);
     if (!module) {
         throw std::runtime_error("Module \""s + moduleName + "\" doesn't exist.");
     }
-    if (module->feature_enable(featureName.c_str())) {
-        throw std::runtime_error("Can't enable feature \""s + featureName + "\" for module \"" + moduleName + "\".");
+    try {
+        module->setImplemented(features);
+    } catch (libyang::ErrorWithCode&) {
+        throw std::runtime_error("Can't enable features for module \"" + moduleName + "\".");
     }
 }
 
 void YangSchema::registerModuleCallback(const std::function<std::string(const char*, const char*, const char*, const char*)>& clb)
 {
-    auto lambda = [clb](const char* mod_name, const char* mod_revision, const char* submod_name, const char* submod_revision) {
+    auto lambda = [clb](const char* mod_name, const char* mod_revision, const char* submod_name, const char* submod_revision) -> std::optional<libyang::ModuleInfo> {
         (void)submod_revision;
         auto moduleSource = clb(mod_name, mod_revision, submod_name, submod_revision);
         if (moduleSource.empty()) {
-            return libyang::Context::mod_missing_cb_return{LYS_IN_YANG, nullptr};
+            return std::nullopt;
         }
-        return libyang::Context::mod_missing_cb_return{LYS_IN_YANG, strdup(moduleSource.c_str())};
+        return libyang::ModuleInfo {
+            .data = moduleSource.c_str(),
+            .format = libyang::SchemaFormat::YANG
+
+        };
     };
 
-    m_context->add_missing_module_callback(lambda, free);
+    m_context.registerModuleCallback(lambda);
 }
 
-std::shared_ptr<libyang::Data_Node> YangSchema::dataNodeFromPath(const std::string& path, const std::optional<const std::string> value) const
+libyang::CreatedNodes YangSchema::dataNodeFromPath(const std::string& path, const std::optional<const std::string> value) const
 {
-    return std::make_shared<libyang::Data_Node>(m_context,
-                                                path.c_str(),
-                                                value ? value.value().c_str() : nullptr,
-                                                LYD_ANYDATA_CONSTSTRING,
-                                                LYD_PATH_OPT_EDIT);
+    auto options = [this, &path, &value] {
+        // If we're creating a node without a value and it's not the "empty" type, then we also need the Opaque flag.
+        auto schema = getSchemaNode(path);
+        if (schema->nodeType() == libyang::NodeType::Leaf &&
+            schema->asLeaf().valueType().base() != libyang::LeafBaseType::Empty &&
+            !value) {
+            return std::optional<libyang::CreationOptions>{libyang::CreationOptions::Opaque};
+        }
+
+        return std::optional<libyang::CreationOptions>{};
+    }();
+    return m_context.newPath2(path.c_str(), value ? value->c_str() : nullptr, options);
 }
 
-std::shared_ptr<libyang::Module> YangSchema::getYangModule(const std::string& name)
+std::optional<libyang::Module> YangSchema::getYangModule(const std::string& name)
 {
-    return m_context->get_module(name.c_str());
+    return m_context.getModuleImplemented(name.c_str());
 }
 
 namespace {
-yang::NodeTypes impl_nodeType(const libyang::S_Schema_Node& node)
+yang::NodeTypes impl_nodeType(const libyang::SchemaNode& node)
 {
-    if (!node) {
-        throw InvalidNodeException();
-    }
-    switch (node->nodetype()) {
-    case LYS_CONTAINER:
-        return libyang::Schema_Node_Container{node}.presence() ? yang::NodeTypes::PresenceContainer : yang::NodeTypes::Container;
-    case LYS_LEAF:
+    switch (node.nodeType()) {
+    case libyang::NodeType::Container:
+        return node.asContainer().isPresence() ? yang::NodeTypes::PresenceContainer : yang::NodeTypes::Container;
+    case libyang::NodeType::Leaf:
         return yang::NodeTypes::Leaf;
-    case LYS_LIST:
+    case libyang::NodeType::List:
         return yang::NodeTypes::List;
-    case LYS_RPC:
+    case libyang::NodeType::RPC:
         return yang::NodeTypes::Rpc;
-    case LYS_ACTION:
+    case libyang::NodeType::Action:
         return yang::NodeTypes::Action;
-    case LYS_NOTIF:
+    case libyang::NodeType::Notification:
         return yang::NodeTypes::Notification;
-    case LYS_ANYXML:
+    case libyang::NodeType::AnyXML:
         return yang::NodeTypes::AnyXml;
-    case LYS_LEAFLIST:
+    case libyang::NodeType::Leaflist:
         return yang::NodeTypes::LeafList;
     default:
         throw InvalidNodeException(); // FIXME: Implement all types.
@@ -507,56 +446,57 @@
 
 yang::NodeTypes YangSchema::nodeType(const schemaPath_& location, const ModuleNodePair& node) const
 {
-    return impl_nodeType(getSchemaNode(location, node));
+    return impl_nodeType(*getSchemaNode(location, node));
 }
 
 yang::NodeTypes YangSchema::nodeType(const std::string& path) const
 {
-    return impl_nodeType(getSchemaNode(path));
+    return impl_nodeType(*getSchemaNode(path));
 }
 
 std::optional<std::string> YangSchema::description(const std::string& path) const
 {
-    auto node = getSchemaNode(path.c_str());
-    return node->dsc() ? std::optional{node->dsc()} : std::nullopt;
+    auto desc = getSchemaNode(path.c_str())->description();
+    return desc ? std::optional<std::string>{desc} : std::nullopt;
+
 }
 
 yang::Status YangSchema::status(const std::string& location) const
 {
     auto node = getSchemaNode(location.c_str());
-    if (node->flags() & LYS_STATUS_DEPRC) {
+    switch (node->status()) {
+    case libyang::Status::Deprecated:
         return yang::Status::Deprecated;
-    } else if (node->flags() & LYS_STATUS_OBSLT) {
+    case libyang::Status::Obsolete:
         return yang::Status::Obsolete;
-    } else {
+    case libyang::Status::Current:
         return yang::Status::Current;
     }
+
+    __builtin_unreachable();
 }
 
 bool YangSchema::hasInputNodes(const std::string& path) const
 {
     auto node = getSchemaNode(path.c_str());
-    if (auto type = node->nodetype(); type != LYS_ACTION && type != LYS_RPC) {
+    if (auto type = node->nodeType(); type != libyang::NodeType::Action && type != libyang::NodeType::RPC) {
         throw std::logic_error("StaticSchema::hasInputNodes called with non-RPC/action path");
     }
 
     // The first child gives the /input node and then I check whether it has a child.
-    return node->child()->child().get();
+    return node->child()->child().has_value();
 }
 
 bool YangSchema::isConfig(const std::string& path) const
 {
     auto node = getSchemaNode(path.c_str());
-    if (node->flags() & LYS_CONFIG_W) {
-        return true;
-    }
-
-    // Node can still be an input node.
-    while (node->parent()) {
-        node = node->parent();
-        if (node->nodetype() == LYS_INPUT) {
+    try {
+        if (node->config() == libyang::Config::True) {
             return true;
         }
+    } catch (libyang::Error&) {
+        // For non-data nodes (like `rpc`), the config value can't be retrieved. In this case, we'll just default to
+        // "false".
     }
 
     return false;
@@ -564,22 +504,10 @@
 
 std::optional<std::string> YangSchema::defaultValue(const std::string& leafPath) const
 {
-    libyang::Schema_Node_Leaf leaf(getSchemaNode(leafPath));
-
-    if (auto leafDefault = leaf.dflt()) {
-        return leafDefault;
-    }
-
-    for (auto type = leaf.type()->der(); type != nullptr; type = type->type()->der()) {
-        if (auto defaultValue = type->dflt()) {
-            return defaultValue;
-        }
-    }
-
-    return std::nullopt;
+    return std::optional<std::string>{getSchemaNode(leafPath)->asLeaf().defaultValueStr()};
 }
 
 std::string YangSchema::dataPathToSchemaPath(const std::string& path)
 {
-    return getSchemaNode(path)->path(LYS_PATH_FIRST_PREFIX);
+    return std::string{getSchemaNode(path)->path()};
 }
diff --git a/src/yang_schema.hpp b/src/yang_schema.hpp
index dc45097..82d9acf 100644
--- a/src/yang_schema.hpp
+++ b/src/yang_schema.hpp
@@ -9,26 +9,19 @@
 #pragma once
 
 #include <functional>
+#include <libyang-cpp/Context.hpp>
 #include <optional>
 #include <set>
 #include "ast_path.hpp"
 #include "schema.hpp"
 
-namespace libyang {
-class Context;
-class Schema_Node;
-class Schema_Node_Leaf;
-class Data_Node;
-class Module;
-}
-
 /*! \class YangSchema
  *     \brief A schema class, which uses libyang for queries.
  *         */
 class YangSchema : public Schema {
 public:
     YangSchema();
-    YangSchema(std::shared_ptr<libyang::Context> lyCtx);
+    YangSchema(libyang::Context lyCtx);
     ~YangSchema() override;
 
     [[nodiscard]] yang::NodeTypes nodeType(const std::string& path) const override;
@@ -54,8 +47,8 @@
     /** @short Loads a module called moduleName. */
     void loadModule(const std::string& moduleName);
 
-    /** @short Enables a feature called featureName on a module called moduleName. */
-    void enableFeature(const std::string& moduleName, const std::string& featureName);
+    /** @short Sets enabled features. */
+    void setEnabledFeatures(const std::string& moduleName, const std::vector<std::string>& features);
 
     /** @short Adds a new module passed as a YANG string. */
     void addSchemaString(const char* schema);
@@ -67,26 +60,26 @@
     void addSchemaDirectory(const char* directoryName);
 
     /** @short Creates a new data node from a path (to be used with NETCONF edit-config) */
-    [[nodiscard]] std::shared_ptr<libyang::Data_Node> dataNodeFromPath(const std::string& path, const std::optional<const std::string> value = std::nullopt) const;
-    std::shared_ptr<libyang::Module> getYangModule(const std::string& name);
+    [[nodiscard]] libyang::CreatedNodes dataNodeFromPath(const std::string& path, const std::optional<const std::string> value = std::nullopt) const;
+    std::optional<libyang::Module> getYangModule(const std::string& name);
 
     [[nodiscard]] std::string dataPathToSchemaPath(const std::string& path);
 
 private:
     friend class YangAccess;
     template <typename NodeType>
-    [[nodiscard]] yang::TypeInfo impl_leafType(const std::shared_ptr<libyang::Schema_Node>& node) const;
+    [[nodiscard]] yang::TypeInfo impl_leafType(const NodeType& node) const;
     [[nodiscard]] std::set<std::string> modules() const;
 
 
-    /** @short Returns a single Schema_Node if the criteria matches only one, otherwise nullptr. */
-    [[nodiscard]] std::shared_ptr<libyang::Schema_Node> getSchemaNode(const std::string& node) const;
-    /** @short Returns a single Schema_Node if the criteria matches only one, otherwise nullptr. */
-    [[nodiscard]] std::shared_ptr<libyang::Schema_Node> getSchemaNode(const schemaPath_& listPath) const;
+    /** @short Returns a single SchemaNode if the criteria matches only one, otherwise nullopt. */
+    [[nodiscard]] std::optional<libyang::SchemaNode> getSchemaNode(const std::string& node) const;
+    /** @short Returns a single Schema_Node if the criteria matches only one, otherwise nullopt. */
+    [[nodiscard]] std::optional<libyang::SchemaNode> getSchemaNode(const schemaPath_& listPath) const;
 
     /** @short Returns a single Schema_Node if the criteria matches only one, otherwise nullptr. */
-    [[nodiscard]] std::shared_ptr<libyang::Schema_Node> getSchemaNode(const schemaPath_& location, const ModuleNodePair& node) const;
-    std::shared_ptr<libyang::Context> m_context;
+    [[nodiscard]] std::optional<libyang::SchemaNode> getSchemaNode(const schemaPath_& location, const ModuleNodePair& node) const;
+    libyang::Context m_context;
 
-    [[nodiscard]] std::shared_ptr<libyang::Schema_Node> impl_getSchemaNode(const std::string& node) const;
+    [[nodiscard]] std::optional<libyang::SchemaNode> impl_getSchemaNode(const std::string& node) const;
 };
