{"id":2469,"date":"2024-02-01T08:17:12","date_gmt":"2024-02-01T08:17:12","guid":{"rendered":"https:\/\/wp-dev.speednet.pl\/?p=2469"},"modified":"2024-02-13T12:16:07","modified_gmt":"2024-02-13T12:16:07","slug":"fullstack-kotlin-developer-part-1","status":"publish","type":"post","link":"https:\/\/speednetsoftware.com\/fullstack-kotlin-developer-part-1\/","title":{"rendered":"Fullstack Kotlin Developer &#8211; part 1"},"content":{"rendered":"\n<p>When perusing job listings, you&#8217;ll often come across the ubiquitous most common phrase &#8220;Fullstack developer wanted&#8221;. If you are a mobile developer with a good <a href=\"https:\/\/speednet.pl\/kotlin-multiplatform-expectations-vs-reality-for-ios-and-android\/\">Kotlin background<\/a>, you are about one step to becoming a full-stack Kotlin developer. That superpower is at your fingertips, so grab it!&nbsp;&nbsp;<\/p>\n\n\n\n<p>In this blog series, I would like to show you how to create a Kotlin multiplatform project based on compose multiplatform that will share common business logic and UI with Android, iOS, and Web applications. Moreover, we will use the same shared business logic on the Backend side of our KTOR application. We can share API interfaces, domain objects, validation rules, and more!&nbsp;&nbsp;<\/p>\n\n\n\n<p>So&#8230; as it is widely known, the beginnings are taught, but the result of your work will be astonishing. Let me guide you through the project setup that will be our base for further development.\u00a0\u00a0<\/p>\n\n\n<nav id=\"toc\" class=\"table-of-content\" role=\"doc-toc\">\n    <h3>\n                    Table of Contents\n            <\/h3>\n    <div class=\"loader\">\n    <div class=\"loader__dot\"><\/div>\n    <div class=\"loader__dot\"><\/div>\n    <div class=\"loader__dot\"><\/div>\n<\/div><\/nav>\n\n\n\n\n<h2 class=\"wp-block-heading\">Let&#8217;s start from scratch&#8230;<\/h2>\n\n\n\n<p>&#8230; and use the project configuration wizard from <a href=\"https:\/\/kmp.jetbrains.com\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">JetBrains<\/a>. Check Android, iOS, and Backend, fill in the project name and ID, and click download. Run this project from the latest version of AndroidStudio or IntelliJ.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"526\" height=\"1024\" src=\"https:\/\/speednet.pl\/app\/uploads\/2024\/01\/Screenshot-2024-01-30-at-05.35.08-526x1024.png\" alt=\"\" class=\"wp-image-2675\" srcset=\"https:\/\/speednetsoftware.com\/app\/uploads\/2024\/01\/Screenshot-2024-01-30-at-05.35.08-526x1024.png 526w, https:\/\/speednetsoftware.com\/app\/uploads\/2024\/01\/Screenshot-2024-01-30-at-05.35.08-154x300.png 154w, https:\/\/speednetsoftware.com\/app\/uploads\/2024\/01\/Screenshot-2024-01-30-at-05.35.08.png 600w\" sizes=\"(max-width: 526px) 100vw, 526px\" \/><\/figure>\n\n\n\n<p>In our Kotlin Multiplatform project, we need to use the latest `compose-plugin` with warm support. Which is still experimental (when I am writing this blog post, the most recent version is 1.6.0-alpha01). Add it to the project, and sync it. The compose plugin version is in the&nbsp;<strong>gradle&nbsp;<\/strong>folder in the&nbsp;<strong>libs.versions.toml,&nbsp;<\/strong>where all dependencies are located.<\/p>\n\n\n\n<p>While the project is syncing, we can inspect the generated template. It is divided into two main sections:&nbsp;<strong>shared&nbsp;<\/strong>and&nbsp;<strong>composeApp.&nbsp;<\/strong>ComposeApp is for the code holding our applications&#8217; Compose Multiplatform code (mostly UI).&nbsp;<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<p>These subfolders correspond to the targets for which we will be launching the application:&nbsp;<\/p>\n<\/div><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<ul class=\"wp-block-list\">\n<li><strong>commonMain<\/strong>&nbsp;is shared code for all platforms&nbsp;<\/li>\n\n\n\n<li><strong>IosMain&nbsp;<\/strong>is for iOS-specific code e.g. apple cryptography<\/li>\n\n\n\n<li><strong>androidMain&nbsp;<\/strong>is for Android code<\/li>\n\n\n\n<li><strong>WasmJsMain&nbsp;<\/strong>is for WebAssembly code<\/li>\n<\/ul>\n<\/div><\/div>\n<\/div><\/div>\n<\/div><\/div>\n\n\n\n<p>The same rules apply to the&nbsp;<strong>shared<\/strong>&nbsp;module where we will hold our business\/domain logic, API requests, and responses, or even the HTTP client. If there is a need to add specific behaviors depending on the platform, we can also use some of the generated subfolders.&nbsp;<\/p>\n\n\n\n<p>The server module is a place where the KTOR backend application is located. It is independent and does not use code from&nbsp;<strong>composeApp&nbsp;<\/strong>or&nbsp;<strong>shared<\/strong>. If we properly structure our code with some additional modules, then we can share part of it even with the backend application (for example, some API models).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Last but not least&#8230;<\/h2>\n\n\n\n<p>&#8230; is the iOSApp module, which contains an iOS application. It&#8217;s an entry point for running the application on Apple devices and a place for the SfiftUI code to be added (if needed).<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"502\" height=\"528\" src=\"https:\/\/speednet.pl\/app\/uploads\/2023\/12\/Screenshot-2023-11-16-at-21.59.09-2.png\" alt=\"\" class=\"wp-image-2477\" srcset=\"https:\/\/speednetsoftware.com\/app\/uploads\/2023\/12\/Screenshot-2023-11-16-at-21.59.09-2.png 502w, https:\/\/speednetsoftware.com\/app\/uploads\/2023\/12\/Screenshot-2023-11-16-at-21.59.09-2-285x300.png 285w\" sizes=\"(max-width: 502px) 100vw, 502px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"502\" height=\"432\" src=\"https:\/\/speednet.pl\/app\/uploads\/2023\/12\/Screenshot-2023-11-16-at-21.59.21-3.png\" alt=\"\" class=\"wp-image-2478\" srcset=\"https:\/\/speednetsoftware.com\/app\/uploads\/2023\/12\/Screenshot-2023-11-16-at-21.59.21-3.png 502w, https:\/\/speednetsoftware.com\/app\/uploads\/2023\/12\/Screenshot-2023-11-16-at-21.59.21-3-300x258.png 300w\" sizes=\"(max-width: 502px) 100vw, 502px\" \/><\/figure>\n<\/figure>\n<\/div><\/div>\n\n\n\n<p>We can add one thing in the&nbsp;<strong>composeApp build.gradle.kts&nbsp;<\/strong>that will run our desired browser for the wasm application; we need to locate the&nbsp;<strong>wasmJs&nbsp;<\/strong>code block and add Google Chrome dev (or other) as a starting point.&nbsp;<\/p>\n\n\n<div class=\"language-javascript\">\n    \n\n<p>wasmJs {&nbsp;<br>&nbsp;&nbsp;&nbsp; moduleName = &#8220;gameshopwasmapp&#8221;&nbsp;<br>&nbsp;&nbsp;&nbsp; browser {&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; commonWebpackConfig {&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outputFileName = &#8220;gameshopwasmapp.js&#8221;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; devServer = (devServer ?: KotlinWebpackConfig.DevServer()).apply {&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; open = mapOf(&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;app&#8221; to mapOf(&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;name&#8221; to &#8220;google chrome dev&#8221;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;<br>&nbsp;&nbsp;&nbsp; }&nbsp;<br>&nbsp;&nbsp;&nbsp; binaries.executable()&nbsp;<br>}&nbsp;<\/p>\n\n\n<\/div>\n\n\n\n\n<p>Before we launch the WASM application, we need to enable its support in our browser. Please follow these <a href=\"https:\/\/kotlinlang.org\/docs\/wasm-get-started.html#troubleshooting\">instructions<\/a>.&nbsp;<\/p>\n\n\n\n<p>Now, we can use the&nbsp;<strong>.\/gradlew :composeApp:wasmJsBrowserDevelopmentRun&nbsp;<\/strong>command to run our application in the browser. To run the Android and iOS apps, you must start proper AndroidStudio configurations.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"282\" height=\"254\" src=\"https:\/\/speednet.pl\/app\/uploads\/2024\/01\/configurations_android_studii.png\" alt=\"\" class=\"wp-image-2674\"\/><\/figure>\n\n\n\n<p>If everything goes well, you can see something like this: click the button to see how the UI changes.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video controls src=\"https:\/\/speednet.pl\/app\/uploads\/2023\/12\/Screen-Recording-2023-11-16-at-22.39.36.webm\"><\/video><\/figure>\n\n\n\n<p>Running the generated project was straightforward. We almost did nothing to make it run. This is a great point to start your project. Get benefits from writing code once and covering three platforms. In the next post, we will add some code to the backend application based on my previous post about the <a href=\"https:\/\/speednet.pl\/ktor-as-a-backend\/\">KTOR<\/a> &#8211; we will extend the existing GameShop by the mobile and frontend applications. <\/p>\n\n\n\n<p>In the following articles, we will discuss a.o. Ktor Server and Client for the application.<\/p>\n\n\n\n<p>Stay tuned and follow us for more!&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When perusing job listings, you&#8217;ll often come across the ubiquitous most common phrase &#8220;Fullstack developer wanted&#8221;. If you are a mobile developer with a good Kotlin background, you are about one step to becoming a full-stack Kotlin developer. That superpower is at your fingertips, so grab it!&nbsp;&nbsp; In this blog series, I would like to [&hellip;]<\/p>\n","protected":false},"author":27,"featured_media":2482,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","footnotes":""},"categories":[38656],"tags":[],"class_list":["post-2469","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-software-development"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.13 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Fullstack Kotlin Developer - part 1 - Speednet<\/title>\n<meta name=\"description\" content=\"Learn how to create a Kotlin multiplatform project based on compose multiplatform with Android, iOS and Web applications.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/speednetsoftware.com\/fullstack-kotlin-developer-part-1\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Fullstack Kotlin Developer - part 1 - Speednet\" \/>\n<meta property=\"og:description\" content=\"Learn how to create a Kotlin multiplatform project based on compose multiplatform with Android, iOS and Web applications.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/speednetsoftware.com\/fullstack-kotlin-developer-part-1\/\" \/>\n<meta property=\"og:site_name\" content=\"Speednet\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/speednetpl\" \/>\n<meta property=\"article:published_time\" content=\"2024-02-01T08:17:12+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-02-13T12:16:07+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/speednetsoftware.com\/app\/uploads\/2023\/12\/Kotlin1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1920\" \/>\n\t<meta property=\"og:image:height\" content=\"1080\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Micha\u0142 Konkel\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Micha\u0142 Konkel\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Fullstack Kotlin Developer - part 1 - Speednet","description":"Learn how to create a Kotlin multiplatform project based on compose multiplatform with Android, iOS and Web applications.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/speednetsoftware.com\/fullstack-kotlin-developer-part-1\/","og_locale":"en_US","og_type":"article","og_title":"Fullstack Kotlin Developer - part 1 - Speednet","og_description":"Learn how to create a Kotlin multiplatform project based on compose multiplatform with Android, iOS and Web applications.","og_url":"https:\/\/speednetsoftware.com\/fullstack-kotlin-developer-part-1\/","og_site_name":"Speednet","article_publisher":"https:\/\/www.facebook.com\/speednetpl","article_published_time":"2024-02-01T08:17:12+00:00","article_modified_time":"2024-02-13T12:16:07+00:00","og_image":[{"width":1920,"height":1080,"url":"https:\/\/speednetsoftware.com\/app\/uploads\/2023\/12\/Kotlin1.png","type":"image\/png"}],"author":"Micha\u0142 Konkel","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Micha\u0142 Konkel","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/speednetsoftware.com\/fullstack-kotlin-developer-part-1\/#article","isPartOf":{"@id":"https:\/\/speednetsoftware.com\/fullstack-kotlin-developer-part-1\/"},"author":{"name":"Micha\u0142 Konkel","@id":"https:\/\/speednetsoftware.com\/#\/schema\/person\/4ac4b38d452fb681c374a7e04d0de5c4"},"headline":"Fullstack Kotlin Developer &#8211; part 1","datePublished":"2024-02-01T08:17:12+00:00","dateModified":"2024-02-13T12:16:07+00:00","mainEntityOfPage":{"@id":"https:\/\/speednetsoftware.com\/fullstack-kotlin-developer-part-1\/"},"wordCount":883,"commentCount":0,"publisher":{"@id":"https:\/\/speednetsoftware.com\/#organization"},"articleSection":["Software development"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/speednetsoftware.com\/fullstack-kotlin-developer-part-1\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/speednetsoftware.com\/fullstack-kotlin-developer-part-1\/","url":"https:\/\/speednetsoftware.com\/fullstack-kotlin-developer-part-1\/","name":"Fullstack Kotlin Developer - part 1 - Speednet","isPartOf":{"@id":"https:\/\/speednetsoftware.com\/#website"},"datePublished":"2024-02-01T08:17:12+00:00","dateModified":"2024-02-13T12:16:07+00:00","description":"Learn how to create a Kotlin multiplatform project based on compose multiplatform with Android, iOS and Web applications.","breadcrumb":{"@id":"https:\/\/speednetsoftware.com\/fullstack-kotlin-developer-part-1\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/speednetsoftware.com\/fullstack-kotlin-developer-part-1\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/speednetsoftware.com\/fullstack-kotlin-developer-part-1\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/speednetsoftware.com\/"},{"@type":"ListItem","position":2,"name":"Fullstack Kotlin Developer &#8211; part 1"}]},{"@type":"WebSite","@id":"https:\/\/speednetsoftware.com\/#website","url":"https:\/\/speednetsoftware.com\/","name":"Speednet","description":"We build software","publisher":{"@id":"https:\/\/speednetsoftware.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/speednetsoftware.com\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/speednetsoftware.com\/#organization","name":"Speednet","alternateName":"Speednet","url":"https:\/\/speednetsoftware.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/speednetsoftware.com\/#\/schema\/logo\/image\/","url":"https:\/\/wp-dev.speednet.pl\/app\/uploads\/2015\/07\/speednetpl_logo.jpg","contentUrl":"https:\/\/wp-dev.speednet.pl\/app\/uploads\/2015\/07\/speednetpl_logo.jpg","width":200,"height":200,"caption":"Speednet"},"image":{"@id":"https:\/\/speednetsoftware.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/speednetpl","https:\/\/www.instagram.com\/speednet.pl\/"]},{"@type":"Person","@id":"https:\/\/speednetsoftware.com\/#\/schema\/person\/4ac4b38d452fb681c374a7e04d0de5c4","name":"Micha\u0142 Konkel","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/speednetsoftware.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/?s=96&d=mm&r=g","caption":"Micha\u0142 Konkel"}}]}},"_links":{"self":[{"href":"https:\/\/speednetsoftware.com\/wp-json\/wp\/v2\/posts\/2469"}],"collection":[{"href":"https:\/\/speednetsoftware.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/speednetsoftware.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/speednetsoftware.com\/wp-json\/wp\/v2\/users\/27"}],"replies":[{"embeddable":true,"href":"https:\/\/speednetsoftware.com\/wp-json\/wp\/v2\/comments?post=2469"}],"version-history":[{"count":25,"href":"https:\/\/speednetsoftware.com\/wp-json\/wp\/v2\/posts\/2469\/revisions"}],"predecessor-version":[{"id":3736,"href":"https:\/\/speednetsoftware.com\/wp-json\/wp\/v2\/posts\/2469\/revisions\/3736"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/speednetsoftware.com\/wp-json\/wp\/v2\/media\/2482"}],"wp:attachment":[{"href":"https:\/\/speednetsoftware.com\/wp-json\/wp\/v2\/media?parent=2469"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/speednetsoftware.com\/wp-json\/wp\/v2\/categories?post=2469"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/speednetsoftware.com\/wp-json\/wp\/v2\/tags?post=2469"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}