There are many third-party client libraries for Kubernetes out there, that’s the wonderful nature of open source software.

The core goals of kr8s are to be readable, beginner-friendly, batteries-included and maintainable above all else. However, other libraries in the ecosystem have different strengths and goals which may better suit the needs of your project.

This page is intended to highlight the differences between kr8s and other libraries to help you make good choices about which library is best for your project.


These comparisons have been put together with the best of intentions, but we acknowledge they are highly subjective and certainly skewed in favour of kr8s. Don’t just take our word for it and be sure to do your own research.

If you spot any information on this page that you beleive to be incorrect or incomplete please don’t hesitate to open a Pull Request. Our goal is to provide you with all the information you need to make the right choice for your needs.

Comparison Table




Repo Stars

Monthly PyPI Downloads

Total conda-forge Downloads


GitHub Repo stars

PyPI - Downloads

Conda Downloads


GitHub Repo stars

PyPI - Downloads

Conda Downloads


GitHub Repo stars

PyPI - Downloads

Conda Downloads


Gitea Repo Stars

PyPI - Downloads

Conda Downloads


GitHub Repo stars

PyPI - Downloads

Conda Downloads

Direct Comparisons

kr8s vs kubernetes

The official kubernetes library maps exactly onto the Kubernetes API due to auto generation. However, this generation results in very verbose code and hard to understand documentation.

In contrast kr8s may not have 100% API coverage with the Kubernetes API but the library is written to be very clear and readable which generally improves code quality. You can also use the low-level API to fill in any missing API gaps that you may need.

Here’s an example comparing listing all Pods using a label selector with kubernetes:

from kubernetes import client, config

selector = {'component': 'kube-scheduler'}
selector_str = ",".join([f"{key}={value}" for key, value in selector.items()])


v1 = client.CoreV1Api()
for pods in v1.list_pod_for_all_namespaces(label_selector=selector_str, ).items:

And here’s the same example with kr8s:

import kr8s

selector = {'component': 'kube-scheduler'}

for pod in kr8s.get("pods", namespace=kr8s.ALL, label_selector=selector):

kr8s vs kubernetes_asyncio

The official kubernetes library doesn’t support asyncio so the kubernetes_asyncio library exists to fill that gap. It is created in the same way by auto generating a library using an asyncio OpenAPI generator.

The code that is needed to use this library is the most verbose out of all of the libraries due to the use of async context managers for HTTP sessions and the documentation is even more minimal than the official library. Often developers need to look at the official docs and then try and translate it into kubernetes_asyncio code.

Here’s an example of listing the Nodes in your cluster with kubernetes-asyncio:

from kubernetes_asyncio import client, config
from kubernetes_asyncio.client.api_client import ApiClient

await config.load_kube_config()

async with ApiClient() as api:
    v1 = client.CoreV1Api(api)
    nodes = await v1.list_node()
    for node in nodes.items:

And here’s the same example with kr8s:

import kr8s.asyncio

for node in await kr8s.asyncio.get("nodes"):

kr8s vs pykube-ng

pykube-ng is a maintained fork of pykube which aims to be a lightweight and pythonic client. It uses no code generation and produces more readable code but doesn’t support asyncio. It also has a very object driven API that appears to be inspired by SQLAlchemy and feels like a traditional ORM which can result in overly complex looking queries to do simple things like get a single resource.

Here’s an example listing ready Pods with pykube-ng:

import pykube

api = pykube.HTTPClient(pykube.KubeConfig.from_file())
for pod in pykube.Pod.objects(api).filter(namespace="kube-system"):
    if pod.ready:

And here’s the same example with kr8s:

import kr8s

for pod in kr8s.get("pods", namespace="kube-system"):
    if pod.ready():

kr8s vs lightkube

Lightkube feels like the Typescript of the Python Kubernetes Client landscape. It has a strong emphasis on type safety and has a partially auto generated codebase to ensure strict schema validation on the client side, but manages to balance that well with a pleasant and pythonic API and supports both sync and async usage.

It feels like the API client that kubernetes + kubernetes_asyncio could’ve been. This is a different design goal to kr8s which is trying to replicate the kubectl experience in Python rather than exposing the Kubernetes HTTP API.

Here’s an example of scaling a Deployment with lightkube:

from lightkube import Client
from lightkube.resources.apps_v1 import Deployment
from lightkube.models.meta_v1 import ObjectMeta
from lightkube.models.autoscaling_v1 import ScaleSpec

client = Client()
deploy = Deployment.Scale(
    metadata=ObjectMeta(name='metrics-server', namespace='kube-system'),

And here’s the same example with kr8s:

from kr8s.objects import Deployment

deploy = Deployment("metrics-server", namespace="kube-system")