diff --git a/docs/source/api/jit.md b/docs/source/api/jit.md
new file mode 100644
index 0000000000000000000000000000000000000000..06ea0cbaf4e5df4c031a102b248b9c1fdc57efad
--- /dev/null
+++ b/docs/source/api/jit.md
@@ -0,0 +1,102 @@
+# JIT Compilation
+
+## Base Infrastructure
+
+```{eval-rst}
+.. module:: pystencils.jit
+
+.. autosummary::
+  :toctree: generated
+  :nosignatures:
+  :template: autosummary/entire_class.rst
+
+    KernelWrapper
+    JitBase
+    NoJit
+
+.. autodata:: no_jit
+```
+
+## Legacy CPU JIT
+
+The legacy CPU JIT Compiler is a leftover from pystencils 1.3
+which at the moment still drives most CPU JIT-compilation within the package,
+until the new JIT compiler is ready to take over.
+
+```{eval-rst}
+.. autosummary::
+  :toctree: generated
+  :nosignatures:
+  :template: autosummary/entire_class.rst
+
+  LegacyCpuJit
+```
+
+## CPU Just-In-Time Compiler
+
+:::{note}
+The new CPU JIT compiler is still considered experimental and not yet adopted by most of pystencils.
+While the APIs described here will (probably) become the default for pystencils 2.0
+and can (and should) already be used for testing,
+the current implementation is still *very slow*.
+For more information, see [issue !120](https://i10git.cs.fau.de/pycodegen/pystencils/-/issues/120).
+:::
+
+To configure and create an instance of the CPU JIT compiler, use the `CpuJit.create` factory method:
+
+:::{card}
+```{eval-rst}
+.. autofunction:: pystencils.jit.CpuJit.create
+  :no-index:
+```
+:::
+
+### Compiler Infos
+
+The CPU JIT compiler invokes a host C++ compiler to compile and link a Python extension
+module containing the generated kernel.
+The properties of the host compiler are defined in a `CompilerInfo` object.
+To select a custom host compiler and customize its options, set up and pass
+a custom compiler info object to `CpuJit.create`.
+
+```{eval-rst}
+.. module:: pystencils.jit.cpu.compiler_info
+
+.. autosummary::
+  :toctree: generated
+  :nosignatures:
+  :template: autosummary/entire_class.rst
+
+  CompilerInfo
+  GccInfo
+  ClangInfo
+```
+
+### Implementation
+
+```{eval-rst}
+.. module:: pystencils.jit.cpu
+
+.. autosummary::
+  :toctree: generated
+  :nosignatures:
+  :template: autosummary/entire_class.rst
+
+  CpuJit
+  cpujit.ExtensionModuleBuilderBase
+```
+
+## CuPy-based GPU JIT
+
+```{eval-rst}
+.. module:: pystencils.jit.gpu_cupy
+
+.. autosummary::
+  :toctree: generated
+  :nosignatures:
+  :template: autosummary/entire_class.rst
+
+  CupyJit
+  CupyKernelWrapper
+  LaunchGrid
+```
diff --git a/docs/source/api/jit.rst b/docs/source/api/jit.rst
deleted file mode 100644
index f2e271db3917825ed7fb6a97c38633a847b8bbfc..0000000000000000000000000000000000000000
--- a/docs/source/api/jit.rst
+++ /dev/null
@@ -1,40 +0,0 @@
-JIT Compilation
-===============
-
-.. module:: pystencils.jit
-
-Base Infrastructure
--------------------
-
-.. autosummary::
-  :toctree: generated
-  :nosignatures:
-  :template: autosummary/entire_class.rst
-
-    KernelWrapper
-    JitBase
-    NoJit
-
-.. autodata:: no_jit
-
-Legacy CPU JIT
---------------
-
-.. autosummary::
-  :toctree: generated
-  :nosignatures:
-  :template: autosummary/entire_class.rst
-
-  LegacyCpuJit
-
-CuPy-based GPU JIT
-------------------
-
-.. autosummary::
-  :toctree: generated
-  :nosignatures:
-  :template: autosummary/entire_class.rst
-
-  CupyJit
-  CupyKernelWrapper
-  LaunchGrid
diff --git a/src/pystencils/codegen/config.py b/src/pystencils/codegen/config.py
index 6587f16b7650d3e3e3f64116cf464ad4e50fa7c6..bce0757313b597cb9f4413e84652b9878c39a2d5 100644
--- a/src/pystencils/codegen/config.py
+++ b/src/pystencils/codegen/config.py
@@ -4,7 +4,7 @@ from warnings import warn
 from abc import ABC
 from collections.abc import Collection
 
-from typing import TYPE_CHECKING, Sequence, Generic, TypeVar, Callable, Any, cast, TypeGuard
+from typing import TYPE_CHECKING, Sequence, Generic, TypeVar, Callable, Any, cast
 from dataclasses import dataclass, InitVar, fields
 
 from .target import Target
@@ -207,7 +207,9 @@ class Category(Generic[Category_T]):
         setattr(obj, self._lookup, cat.copy() if cat is not None else None)
 
 
-class _AUTO_TYPE: ...  # noqa: E701
+class _AUTO_TYPE:
+    def __repr__(self) -> str:
+        return "AUTO"  # for pretty-printing in the docs
 
 
 AUTO = _AUTO_TYPE()
diff --git a/src/pystencils/jit/cpu/compiler_info.py b/src/pystencils/jit/cpu/compiler_info.py
index 6ed568d72d28b4254825bd3e84901f5f3b48c5be..061f37af50e9903707f823b98c390b89230efc33 100644
--- a/src/pystencils/jit/cpu/compiler_info.py
+++ b/src/pystencils/jit/cpu/compiler_info.py
@@ -8,28 +8,43 @@ from ...codegen.target import Target
 
 @dataclass
 class CompilerInfo(ABC):
+    """Base class for compiler infos."""
+
     openmp: bool = True
+    """Enable/disable OpenMP compilation"""
 
     optlevel: str | None = "fast"
+    """Compiler optimization level"""
 
     cxx_standard: str = "c++11"
+    """C++ language standard to be compiled with"""
 
     target: Target = Target.CurrentCPU
+    """Hardware target to compile for.
+    
+    Here, `Target.CurrentCPU` represents the current hardware,
+    which is reflected by ``-march=native`` in GNU-like compilers.
+    """
 
     @abstractmethod
-    def cxx(self) -> str: ...
+    def cxx(self) -> str:
+        """Path to the executable of this compiler"""
 
     @abstractmethod
-    def cxxflags(self) -> list[str]: ...
+    def cxxflags(self) -> list[str]:
+        """Compiler flags affecting C++ compilation"""
 
     @abstractmethod
-    def linker_flags(self) -> list[str]: ...
+    def linker_flags(self) -> list[str]:
+        """Flags affecting linkage of the extension module"""
 
     @abstractmethod
-    def include_flags(self, include_dirs: Sequence[str]) -> list[str]: ...
+    def include_flags(self, include_dirs: Sequence[str]) -> list[str]:
+        """Convert a list of include directories into corresponding compiler flags"""
 
     @abstractmethod
-    def restrict_qualifier(self) -> str: ...
+    def restrict_qualifier(self) -> str:
+        """*restrict* memory qualifier recognized by this compiler"""
 
 
 class _GnuLikeCliCompiler(CompilerInfo):
@@ -67,13 +82,18 @@ class _GnuLikeCliCompiler(CompilerInfo):
 
 
 class GccInfo(_GnuLikeCliCompiler):
+    """Compiler info for the GNU Compiler Collection C++ compiler (``g++``)."""
+
     def cxx(self) -> str:
         return "g++"
 
 
 @dataclass
 class ClangInfo(_GnuLikeCliCompiler):
+    """Compiler info for the LLVM C++ compiler (``clang``)."""
+    
     llvm_version: int | None = None
+    """Major version number of the LLVM installation providing the compiler."""
 
     def cxx(self) -> str:
         if self.llvm_version is None:
@@ -81,5 +101,5 @@ class ClangInfo(_GnuLikeCliCompiler):
         else:
             return f"clang-{self.llvm_version}"
         
-    def cxxflags(self) -> list[str]:
-        return super().cxxflags() + ["-lstdc++"]
+    def linker_flags(self) -> list[str]:
+        return super().linker_flags() + ["-lstdc++"]
diff --git a/src/pystencils/jit/cpu/cpujit.py b/src/pystencils/jit/cpu/cpujit.py
index 64045d54951639b47e7beb3d2d99def8db6ce304..5fce101ee716de053df23687580b312d3ba76ac4 100644
--- a/src/pystencils/jit/cpu/cpujit.py
+++ b/src/pystencils/jit/cpu/cpujit.py
@@ -16,24 +16,45 @@ from .compiler_info import CompilerInfo, GccInfo
 class CpuJit(JitBase):
     """Just-in-time compiler for CPU kernels.
 
-    :Creation:
-    In most cases, objects of this class should be instantiated using the `create` factory method.
-
-    :Implementation Details:
-
-    The `CpuJit` combines two separate components:
-    - The *extension module builder* produces the code of the dynamically built extension module containing
-      the kernel
-    - The *compiler info* describes the system compiler used to compile and link that extension module.
-
-    Both can be dynamically exchanged.
+    **Creation**
+    
+    To configure and create a CPU JIT compiler instance, use the `create` factory method.
+
+    **Implementation Details**
+
+    The `CpuJit` class acts as an orchestrator between two components:
+    
+    - The *extension module builder* produces the code of the dynamically built extension module
+      that contains the kernel and its invocation wrappers;
+    - The *compiler info* describes the host compiler used to compile and link that extension module.
+
+    Args:
+        compiler_info: The compiler info object defining the capabilities
+            and command-line interface of the host compiler
+        ext_module_builder: Extension module builder object used to generate the kernel extension module
+        objcache: Directory to cache the generated code files and compiled modules in.
+            If `None`, a temporary directory will be used, and compilation results will not be cached.
     """
 
     @staticmethod
     def create(
         compiler_info: CompilerInfo | None = None,
         objcache: str | Path | _AUTO_TYPE | None = AUTO,
-    ):
+    ) -> CpuJit:
+        """Configure and create a CPU JIT compiler object.
+        
+        Args:
+            compiler_info: Compiler info object defining capabilities and interface of the host compiler.
+                If `None`, a default compiler configuration will be determined from the current OS and runtime
+                environment.
+            objcache: Directory used for caching compilation results.
+                If set to `AUTO`, a persistent cache directory in the current user's home will be used.
+                If set to `None`, compilation results will not be cached--this may impact performance.
+
+        Returns:
+            The CPU just-in-time compiler.
+        """
+        
         if objcache is AUTO:
             from appdirs import AppDirs
 
@@ -82,34 +103,19 @@ class CpuJit(JitBase):
             + self._compiler_info.linker_flags()
         )
 
-    @property
-    def objcache(self) -> Path | None:
-        return self._objcache
-
-    @property
-    def compiler_info(self) -> CompilerInfo:
-        return self._compiler_info
-
-    @compiler_info.setter
-    def compiler_info(self, info: CompilerInfo):
-        self._compiler_info = info
-
-    @property
-    def strict_scalar_types(self) -> bool:
-        """Enable or disable implicit type casts for scalar parameters.
-
-        If `True`, values for scalar kernel parameters must always be provided with the correct NumPy type.
+    def compile(self, kernel: Kernel) -> KernelWrapper:
+        """Compile the given kernel to an executable function.
+        
+        Args:
+            kernel: The kernel object to be compiled.
+        
+        Returns:
+            Wrapper object around the compiled function
         """
-        return self._strict_scalar_types
 
-    @strict_scalar_types.setter
-    def strict_scalar_types(self, v: bool):
-        self._strict_scalar_types = v
-
-    def compile(self, kernel: Kernel) -> KernelWrapper:
         #   Get the Code
         module_name = f"{kernel.function_name}_jit"
-        cpp_code = self._ext_module_builder(kernel, module_name)
+        cpp_code = self._ext_module_builder.render_module(kernel, module_name)
 
         #   Get compiler information
         import sysconfig
@@ -181,14 +187,21 @@ class CpuJit(JitBase):
 
 
 class ExtensionModuleBuilderBase(ABC):
+    """Base class for CPU extension module builders."""
+
     @staticmethod
     @abstractmethod
-    def include_dirs() -> list[str]: ...
+    def include_dirs() -> list[str]:
+        """List of directories that must be on the include path when compiling
+        generated extension modules."""
 
     @abstractmethod
-    def __call__(self, kernel: Kernel, module_name: str) -> str: ...
+    def render_module(self, kernel: Kernel, module_name: str) -> str:
+        """Produce the extension module code for the given kernel."""
 
     @abstractmethod
     def get_wrapper(
         self, kernel: Kernel, extension_module: ModuleType
-    ) -> KernelWrapper: ...
+    ) -> KernelWrapper:
+        """Produce the invocation wrapper for the given kernel
+        and its compiled extension module."""
diff --git a/src/pystencils/jit/cpu/cpujit_pybind11.py b/src/pystencils/jit/cpu/cpujit_pybind11.py
index 2f43ef1965278eb3148fbfb448a9cfb001542adf..1742bf30113f418e5a701db15f75f47bb2882a8d 100644
--- a/src/pystencils/jit/cpu/cpujit_pybind11.py
+++ b/src/pystencils/jit/cpu/cpujit_pybind11.py
@@ -43,7 +43,7 @@ class Pybind11KernelModuleBuilder(ExtensionModuleBuilderBase):
         self._param_check_lines: list[str]
         self._extraction_lines: list[str]
 
-    def __call__(self, kernel: Kernel, module_name: str) -> str:
+    def render_module(self, kernel: Kernel, module_name: str) -> str:
         self._actual_field_types = dict()
         self._param_binds = []
         self._public_params = []