diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..d8e1939df05ff5cafa50764cb4b11eadee35e309
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,31 @@
+image: maven:3-eclipse-temurin-17
+
+variables:
+  MAVEN_OPTS: "-Dhttps.protocols=TLSv1.2 -Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true"
+  MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version"
+
+cache:
+  key: "$CI_JOB_NAME"
+  paths:
+    - .m2/repository
+
+stages:
+  - build
+  - deploy
+
+build:
+  stage: build
+  script:
+    - ./processor.sh
+    - mvn install -s ci_settings.xml
+  artifacts:
+    paths:
+      - target/
+      - src/
+
+deploy:
+  stage: deploy
+  rules:
+    - if: $CI_COMMIT_TAG
+  script:
+    - mvn deploy -s ci_settings.xml
diff --git a/ci_settings.xml b/ci_settings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..59c8c271cb4549ebcad535c1c9e1907839ba440f
--- /dev/null
+++ b/ci_settings.xml
@@ -0,0 +1,16 @@
+<settings xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd">
+  <servers>
+    <server>
+      <id>gitlab-maven</id>
+      <configuration>
+        <httpHeaders>
+          <property>
+            <name>Job-Token</name>
+            <value>${env.CI_JOB_TOKEN}</value>
+          </property>
+        </httpHeaders>
+      </configuration>
+    </server>
+  </servers>
+</settings>
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2b1e779fe07ce6caa858d93b2ff5ed222d7becb5
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,129 @@
+<project>
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>io.github.davidepianca98</groupId>
+    <artifactId>kmqtt</artifactId>
+    <version>1.0.0-jpms</version>
+    <name>MQTT client by io.github.davidepianca98</name>
+    <packaging>jar</packaging>
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <kotlin.compiler.incremental>true</kotlin.compiler.incremental>
+        <jdk.version>17</jdk.version>
+        <kotlin.version>2.1.20</kotlin.version>
+        <junit.version>5.10.2</junit.version>
+        <junitplatform.version>1.10.2</junitplatform.version>
+    </properties>
+    <repositories>
+        <repository>
+            <id>central</id>
+            <name>Central Repository</name>
+            <url>https://repo.maven.apache.org/maven2</url>
+        </repository>
+    </repositories>
+    <dependencies>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-api</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-params</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.platform</groupId>
+            <artifactId>junit-platform-commons</artifactId>
+            <version>${junitplatform.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.jetbrains.kotlin</groupId>
+            <artifactId>kotlin-stdlib</artifactId>
+            <version>${kotlin.version}</version>
+        </dependency><!--
+        <dependency>
+            <groupId>org.jetbrains.kotlinx</groupId>
+            <artifactId>kotlinx-coroutines-core-jvm</artifactId>
+            <version>1.9.0</version>
+        </dependency>-->
+        <dependency>
+            <groupId>org.jetbrains.kotlinx</groupId>
+            <artifactId>atomicfu-jvm</artifactId>
+            <version>0.27.0</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>3.3.0</version>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.10.1</version>
+                <configuration>
+                    <source>${jdk.version}</source>
+                    <target>${jdk.version}</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+                <version>3.1.0</version>
+                <executions>
+                    <execution>
+                        <id>attach-sources</id>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.jetbrains.kotlin</groupId>
+                <artifactId>kotlin-maven-plugin</artifactId>
+                <version>${kotlin.version}</version>
+                <executions>
+                    <execution>
+                        <id>compile</id>
+                        <phase>process-sources</phase>
+                        <goals>
+                            <goal>compile</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>test-compile</id>
+                        <phase>test-compile</phase>
+                        <goals>
+                            <goal>test-compile</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <jvmTarget>${jdk.version}</jvmTarget>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <distributionManagement>
+        <repository>
+            <id>gitlab-maven</id>
+            <url>${env.CI_API_V4_URL}/projects/${env.CI_PROJECT_ID}/packages/maven</url>
+        </repository>
+        <snapshotRepository>
+            <id>gitlab-maven</id>
+            <url>${env.CI_API_V4_URL}/projects/${env.CI_PROJECT_ID}/packages/maven</url>
+        </snapshotRepository>
+    </distributionManagement>
+</project>
\ No newline at end of file
diff --git a/processor.sh b/processor.sh
new file mode 100755
index 0000000000000000000000000000000000000000..3a91aafea495d730279bd3dbc8f8ddf8f810ba86
--- /dev/null
+++ b/processor.sh
@@ -0,0 +1,18 @@
+# merge the sources for a jvm only build
+for m in kmqtt-common kmqtt-client; do
+  cp -r $m/src/commonMain/kotlin/* src/main/java/
+  cp -r $m/src/jvmMain/kotlin/* src/main/java/
+done
+
+for f in $(find src/ -type f -name '*kt'); do
+  # disable coroutines
+  sed -i 's/import kotlinx.coroutines/\/\//g' "$f"
+  sed -i '/^ *public fun runSuspend(/,/^ *$/d' src/main/java/io/github/davidepianca98/MQTTClient.kt
+  sed -i '/^ *public fun initAndRunSuspend(/,/^ *$/d' src/main/java/io/github/davidepianca98/MQTTClient.kt
+  # simplify locking
+  sed -i 's/private val lock = ReentrantLock()/private val lock = Object()/g' "$f"
+  sed -i 's/lock.withLock/synchronized(lock)/g' "$f"
+  # remove expect/actual annotations
+  sed -i "s/^public expect fun.*//g" "$f"
+  sed -i "s/actual \(fun\|val\|annotation\|constructor\|class\|override\|open\)/\1/g" "$f"
+done
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..95a4639e2cbe72c7a7037672c5aea3719814cd51
--- /dev/null
+++ b/src/main/java/module-info.java
@@ -0,0 +1,15 @@
+module io.github.davidepianca98 {
+    requires kotlin.stdlib;
+    requires kotlinx.atomicfu;
+    //requires kotlinx.coroutines.core;
+    exports io.github.davidepianca98;
+    exports io.github.davidepianca98.mqtt;
+    exports io.github.davidepianca98.mqtt.packets;
+    exports io.github.davidepianca98.mqtt.packets.mqtt;
+    exports io.github.davidepianca98.mqtt.packets.mqttv4;
+    exports io.github.davidepianca98.mqtt.packets.mqttv5;
+    exports io.github.davidepianca98.socket;
+    exports io.github.davidepianca98.socket.streams;
+    exports io.github.davidepianca98.socket.tcp;
+    exports io.github.davidepianca98.socket.tls;
+}