diff --git a/build.gradle.kts b/build.gradle.kts
index 89f810b..001050e 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -34,6 +34,9 @@ group = projectGroup
 version = projectVersion
 
 kotlin {
+    // Since we are a library, prevent accidentally making things part of the public API
+    explicitApi()
+
     sourceSets.all {
         languageSettings {
             languageVersion = kotlinApiTarget
diff --git a/src/commonMain/kotlin/io/konform/validation/Validation.kt b/src/commonMain/kotlin/io/konform/validation/Validation.kt
index ddeefdf..c992e79 100644
--- a/src/commonMain/kotlin/io/konform/validation/Validation.kt
+++ b/src/commonMain/kotlin/io/konform/validation/Validation.kt
@@ -2,17 +2,21 @@ package io.konform.validation
 
 import io.konform.validation.internal.ValidationBuilderImpl
 
-interface Validation<T> {
-    companion object {
-        operator fun <T> invoke(init: ValidationBuilder<T>.() -> Unit): Validation<T> {
+public interface Validation<T> {
+    public companion object {
+        public operator fun <T> invoke(init: ValidationBuilder<T>.() -> Unit): Validation<T> {
             val builder = ValidationBuilderImpl<T>()
             return builder.apply(init).build()
         }
     }
 
-    fun validate(value: T): ValidationResult<T>
+    public fun validate(value: T): ValidationResult<T>
 
-    operator fun invoke(value: T) = validate(value)
+    public operator fun invoke(value: T): ValidationResult<T> = validate(value)
 }
 
-class Constraint<R> internal constructor(val hint: String, val templateValues: List<String>, val test: (R) -> Boolean)
+public class Constraint<R> internal constructor(
+    public val hint: String,
+    public val templateValues: List<String>,
+    public val test: (R) -> Boolean,
+)
diff --git a/src/commonMain/kotlin/io/konform/validation/ValidationBuilder.kt b/src/commonMain/kotlin/io/konform/validation/ValidationBuilder.kt
index 666248c..aece51e 100644
--- a/src/commonMain/kotlin/io/konform/validation/ValidationBuilder.kt
+++ b/src/commonMain/kotlin/io/konform/validation/ValidationBuilder.kt
@@ -13,18 +13,18 @@ import kotlin.reflect.KProperty1
 private annotation class ValidationScope
 
 @ValidationScope
-abstract class ValidationBuilder<T> {
-    abstract fun build(): Validation<T>
+public abstract class ValidationBuilder<T> {
+    public abstract fun build(): Validation<T>
 
-    abstract fun addConstraint(
+    public abstract fun addConstraint(
         errorMessage: String,
         vararg templateValues: String,
         test: (T) -> Boolean,
     ): Constraint<T>
 
-    abstract infix fun Constraint<T>.hint(hint: String): Constraint<T>
+    public abstract infix fun Constraint<T>.hint(hint: String): Constraint<T>
 
-    abstract operator fun <R> KProperty1<T, R>.invoke(init: ValidationBuilder<R>.() -> Unit)
+    public abstract operator fun <R> KProperty1<T, R>.invoke(init: ValidationBuilder<R>.() -> Unit)
 
     internal abstract fun <R> onEachIterable(
         prop: KProperty1<T, Iterable<R>>,
@@ -32,7 +32,7 @@ abstract class ValidationBuilder<T> {
     )
 
     @JvmName("onEachIterable")
-    infix fun <R> KProperty1<T, Iterable<R>>.onEach(init: ValidationBuilder<R>.() -> Unit) = onEachIterable(this, init)
+    public infix fun <R> KProperty1<T, Iterable<R>>.onEach(init: ValidationBuilder<R>.() -> Unit): Unit = onEachIterable(this, init)
 
     internal abstract fun <R> onEachArray(
         prop: KProperty1<T, Array<R>>,
@@ -40,7 +40,7 @@ abstract class ValidationBuilder<T> {
     )
 
     @JvmName("onEachArray")
-    infix fun <R> KProperty1<T, Array<R>>.onEach(init: ValidationBuilder<R>.() -> Unit) = onEachArray(this, init)
+    public infix fun <R> KProperty1<T, Array<R>>.onEach(init: ValidationBuilder<R>.() -> Unit): Unit = onEachArray(this, init)
 
     internal abstract fun <K, V> onEachMap(
         prop: KProperty1<T, Map<K, V>>,
@@ -48,31 +48,32 @@ abstract class ValidationBuilder<T> {
     )
 
     @JvmName("onEachMap")
-    infix fun <K, V> KProperty1<T, Map<K, V>>.onEach(init: ValidationBuilder<Map.Entry<K, V>>.() -> Unit) = onEachMap(this, init)
+    public infix fun <K, V> KProperty1<T, Map<K, V>>.onEach(init: ValidationBuilder<Map.Entry<K, V>>.() -> Unit): Unit =
+        onEachMap(this, init)
 
-    abstract infix fun <R> KProperty1<T, R?>.ifPresent(init: ValidationBuilder<R>.() -> Unit)
+    public abstract infix fun <R> KProperty1<T, R?>.ifPresent(init: ValidationBuilder<R>.() -> Unit)
 
-    abstract infix fun <R> KProperty1<T, R?>.required(init: ValidationBuilder<R>.() -> Unit)
+    public abstract infix fun <R> KProperty1<T, R?>.required(init: ValidationBuilder<R>.() -> Unit)
 
-    abstract fun run(validation: Validation<T>)
+    public abstract fun run(validation: Validation<T>)
 
-    abstract val <R> KProperty1<T, R>.has: ValidationBuilder<R>
+    public abstract val <R> KProperty1<T, R>.has: ValidationBuilder<R>
 }
 
-fun <T : Any> ValidationBuilder<T?>.ifPresent(init: ValidationBuilder<T>.() -> Unit) {
+public fun <T : Any> ValidationBuilder<T?>.ifPresent(init: ValidationBuilder<T>.() -> Unit) {
     val builder = ValidationBuilderImpl<T>()
     init(builder)
     run(OptionalValidation(builder.build()))
 }
 
-fun <T : Any> ValidationBuilder<T?>.required(init: ValidationBuilder<T>.() -> Unit) {
+public fun <T : Any> ValidationBuilder<T?>.required(init: ValidationBuilder<T>.() -> Unit) {
     val builder = ValidationBuilderImpl<T>()
     init(builder)
     run(RequiredValidation(builder.build()))
 }
 
 @JvmName("onEachIterable")
-fun <S, T : Iterable<S>> ValidationBuilder<T>.onEach(init: ValidationBuilder<S>.() -> Unit) {
+public fun <S, T : Iterable<S>> ValidationBuilder<T>.onEach(init: ValidationBuilder<S>.() -> Unit) {
     val builder = ValidationBuilderImpl<S>()
     init(builder)
     @Suppress("UNCHECKED_CAST")
@@ -80,7 +81,7 @@ fun <S, T : Iterable<S>> ValidationBuilder<T>.onEach(init: ValidationBuilder<S>.
 }
 
 @JvmName("onEachArray")
-fun <T> ValidationBuilder<Array<T>>.onEach(init: ValidationBuilder<T>.() -> Unit) {
+public fun <T> ValidationBuilder<Array<T>>.onEach(init: ValidationBuilder<T>.() -> Unit) {
     val builder = ValidationBuilderImpl<T>()
     init(builder)
     @Suppress("UNCHECKED_CAST")
@@ -88,7 +89,7 @@ fun <T> ValidationBuilder<Array<T>>.onEach(init: ValidationBuilder<T>.() -> Unit
 }
 
 @JvmName("onEachMap")
-fun <K, V, T : Map<K, V>> ValidationBuilder<T>.onEach(init: ValidationBuilder<Map.Entry<K, V>>.() -> Unit) {
+public fun <K, V, T : Map<K, V>> ValidationBuilder<T>.onEach(init: ValidationBuilder<Map.Entry<K, V>>.() -> Unit) {
     val builder = ValidationBuilderImpl<Map.Entry<K, V>>()
     init(builder)
     @Suppress("UNCHECKED_CAST")
diff --git a/src/commonMain/kotlin/io/konform/validation/ValidationResult.kt b/src/commonMain/kotlin/io/konform/validation/ValidationResult.kt
index 6cddfff..6521a76 100644
--- a/src/commonMain/kotlin/io/konform/validation/ValidationResult.kt
+++ b/src/commonMain/kotlin/io/konform/validation/ValidationResult.kt
@@ -2,9 +2,9 @@ package io.konform.validation
 
 import kotlin.reflect.KProperty1
 
-interface ValidationError {
-    val dataPath: String
-    val message: String
+public interface ValidationError {
+    public val dataPath: String
+    public val message: String
 }
 
 internal data class PropertyValidationError(
@@ -16,7 +16,7 @@ internal data class PropertyValidationError(
     }
 }
 
-interface ValidationErrors : List<ValidationError>
+public interface ValidationErrors : List<ValidationError>
 
 internal object NoValidationErrors : ValidationErrors, List<ValidationError> by emptyList()
 
@@ -26,15 +26,15 @@ internal class DefaultValidationErrors(private val errors: List<ValidationError>
     }
 }
 
-sealed class ValidationResult<out T> {
-    abstract operator fun get(vararg propertyPath: Any): List<String>?
+public sealed class ValidationResult<out T> {
+    public abstract operator fun get(vararg propertyPath: Any): List<String>?
 
-    abstract fun <R> map(transform: (T) -> R): ValidationResult<R>
+    public abstract fun <R> map(transform: (T) -> R): ValidationResult<R>
 
-    abstract val errors: ValidationErrors
+    public abstract val errors: ValidationErrors
 }
 
-data class Invalid<T>(
+public data class Invalid<T>(
     internal val internalErrors: Map<String, List<String>>,
 ) : ValidationResult<T>() {
     override fun get(vararg propertyPath: Any): List<String>? = internalErrors[propertyPath.joinToString("", transform = ::toPathSegment)]
@@ -62,7 +62,7 @@ data class Invalid<T>(
     }
 }
 
-data class Valid<T>(val value: T) : ValidationResult<T>() {
+public data class Valid<T>(val value: T) : ValidationResult<T>() {
     override fun get(vararg propertyPath: Any): List<String>? = null
 
     override fun <R> map(transform: (T) -> R): ValidationResult<R> = Valid(transform(this.value))
diff --git a/src/commonMain/kotlin/io/konform/validation/jsonschema/JsonSchema.kt b/src/commonMain/kotlin/io/konform/validation/jsonschema/JsonSchema.kt
index cab5539..2bef18d 100644
--- a/src/commonMain/kotlin/io/konform/validation/jsonschema/JsonSchema.kt
+++ b/src/commonMain/kotlin/io/konform/validation/jsonschema/JsonSchema.kt
@@ -4,18 +4,18 @@ import io.konform.validation.Constraint
 import io.konform.validation.ValidationBuilder
 import kotlin.math.roundToInt
 
-inline fun <reified T> ValidationBuilder<*>.type() =
+public inline fun <reified T> ValidationBuilder<*>.type(): Constraint<*> =
     addConstraint(
         "must be of the correct type",
     ) { it is T }
 
-fun <T> ValidationBuilder<T>.enum(vararg allowed: T) =
+public fun <T> ValidationBuilder<T>.enum(vararg allowed: T): Constraint<T> =
     addConstraint(
         "must be one of: {0}",
         allowed.joinToString("', '", "'", "'"),
     ) { it in allowed }
 
-inline fun <reified T : Enum<T>> ValidationBuilder<String>.enum(): Constraint<String> {
+public inline fun <reified T : Enum<T>> ValidationBuilder<String>.enum(): Constraint<String> {
     val enumNames = enumValues<T>().map { it.name }
     return addConstraint(
         "must be one of: {0}",
@@ -23,13 +23,13 @@ inline fun <reified T : Enum<T>> ValidationBuilder<String>.enum(): Constraint<St
     ) { it in enumNames }
 }
 
-fun <T> ValidationBuilder<T>.const(expected: T) =
+public fun <T> ValidationBuilder<T>.const(expected: T): Constraint<T> =
     addConstraint(
         "must be {0}",
         expected?.let { "'$it'" } ?: "null",
     ) { expected == it }
 
-fun <T : Number> ValidationBuilder<T>.multipleOf(factor: Number): Constraint<T> {
+public fun <T : Number> ValidationBuilder<T>.multipleOf(factor: Number): Constraint<T> {
     val factorAsDouble = factor.toDouble()
     require(factorAsDouble > 0) { "multipleOf requires the factor to be strictly larger than 0" }
     return addConstraint("must be a multiple of '{0}'", factor.toString()) {
@@ -38,31 +38,31 @@ fun <T : Number> ValidationBuilder<T>.multipleOf(factor: Number): Constraint<T>
     }
 }
 
-fun <T : Number> ValidationBuilder<T>.maximum(maximumInclusive: Number) =
+public fun <T : Number> ValidationBuilder<T>.maximum(maximumInclusive: Number): Constraint<T> =
     addConstraint(
         "must be at most '{0}'",
         maximumInclusive.toString(),
     ) { it.toDouble() <= maximumInclusive.toDouble() }
 
-fun <T : Number> ValidationBuilder<T>.exclusiveMaximum(maximumExclusive: Number) =
+public fun <T : Number> ValidationBuilder<T>.exclusiveMaximum(maximumExclusive: Number): Constraint<T> =
     addConstraint(
         "must be less than '{0}'",
         maximumExclusive.toString(),
     ) { it.toDouble() < maximumExclusive.toDouble() }
 
-fun <T : Number> ValidationBuilder<T>.minimum(minimumInclusive: Number) =
+public fun <T : Number> ValidationBuilder<T>.minimum(minimumInclusive: Number): Constraint<T> =
     addConstraint(
         "must be at least '{0}'",
         minimumInclusive.toString(),
     ) { it.toDouble() >= minimumInclusive.toDouble() }
 
-fun <T : Number> ValidationBuilder<T>.exclusiveMinimum(minimumExclusive: Number) =
+public fun <T : Number> ValidationBuilder<T>.exclusiveMinimum(minimumExclusive: Number): Constraint<T> =
     addConstraint(
         "must be greater than '{0}'",
         minimumExclusive.toString(),
     ) { it.toDouble() > minimumExclusive.toDouble() }
 
-fun ValidationBuilder<String>.minLength(length: Int): Constraint<String> {
+public fun ValidationBuilder<String>.minLength(length: Int): Constraint<String> {
     require(length >= 0) { IllegalArgumentException("minLength requires the length to be >= 0") }
     return addConstraint(
         "must have at least {0} characters",
@@ -70,7 +70,7 @@ fun ValidationBuilder<String>.minLength(length: Int): Constraint<String> {
     ) { it.length >= length }
 }
 
-fun ValidationBuilder<String>.maxLength(length: Int): Constraint<String> {
+public fun ValidationBuilder<String>.maxLength(length: Int): Constraint<String> {
     require(length >= 0) { IllegalArgumentException("maxLength requires the length to be >= 0") }
     return addConstraint(
         "must have at most {0} characters",
@@ -78,15 +78,15 @@ fun ValidationBuilder<String>.maxLength(length: Int): Constraint<String> {
     ) { it.length <= length }
 }
 
-fun ValidationBuilder<String>.pattern(pattern: String) = pattern(pattern.toRegex())
+public fun ValidationBuilder<String>.pattern(pattern: String): Constraint<String> = pattern(pattern.toRegex())
 
-fun ValidationBuilder<String>.pattern(pattern: Regex) =
+public fun ValidationBuilder<String>.pattern(pattern: Regex): Constraint<String> =
     addConstraint(
         "must match the expected pattern",
         pattern.toString(),
     ) { it.matches(pattern) }
 
-inline fun <reified T> ValidationBuilder<T>.minItems(minSize: Int): Constraint<T> =
+public inline fun <reified T> ValidationBuilder<T>.minItems(minSize: Int): Constraint<T> =
     addConstraint(
         "must have at least {0} items",
         minSize.toString(),
@@ -99,7 +99,7 @@ inline fun <reified T> ValidationBuilder<T>.minItems(minSize: Int): Constraint<T
         }
     }
 
-inline fun <reified T> ValidationBuilder<T>.maxItems(maxSize: Int): Constraint<T> =
+public inline fun <reified T> ValidationBuilder<T>.maxItems(maxSize: Int): Constraint<T> =
     addConstraint(
         "must have at most {0} items",
         maxSize.toString(),
@@ -112,13 +112,13 @@ inline fun <reified T> ValidationBuilder<T>.maxItems(maxSize: Int): Constraint<T
         }
     }
 
-inline fun <reified T : Map<*, *>> ValidationBuilder<T>.minProperties(minSize: Int): Constraint<T> =
+public inline fun <reified T : Map<*, *>> ValidationBuilder<T>.minProperties(minSize: Int): Constraint<T> =
     minItems(minSize) hint "must have at least {0} properties"
 
-inline fun <reified T : Map<*, *>> ValidationBuilder<T>.maxProperties(maxSize: Int): Constraint<T> =
+public inline fun <reified T : Map<*, *>> ValidationBuilder<T>.maxProperties(maxSize: Int): Constraint<T> =
     maxItems(maxSize) hint "must have at most {0} properties"
 
-inline fun <reified T> ValidationBuilder<T>.uniqueItems(unique: Boolean): Constraint<T> =
+public inline fun <reified T> ValidationBuilder<T>.uniqueItems(unique: Boolean): Constraint<T> =
     addConstraint(
         "all items must be unique",
     ) {