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()};
 }
