{"id":20544766,"url":"https://github.com/bbodi/kotlinreactspringbootstrap","last_synced_at":"2026-05-27T13:31:14.314Z","repository":{"id":148704562,"uuid":"51998922","full_name":"bbodi/KotlinReactSpringBootstrap","owner":"bbodi","description":"A web application framework and structure template using Kotlin, React and Spring. It makes easier to start new projects from scratch.","archived":false,"fork":false,"pushed_at":"2016-02-24T12:53:22.000Z","size":864,"stargazers_count":1,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-16T15:47:36.800Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bbodi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-02-18T10:18:17.000Z","updated_at":"2018-03-01T04:41:05.000Z","dependencies_parsed_at":"2023-05-07T12:16:46.517Z","dependency_job_id":null,"html_url":"https://github.com/bbodi/KotlinReactSpringBootstrap","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbodi%2FKotlinReactSpringBootstrap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbodi%2FKotlinReactSpringBootstrap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbodi%2FKotlinReactSpringBootstrap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbodi%2FKotlinReactSpringBootstrap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bbodi","download_url":"https://codeload.github.com/bbodi/KotlinReactSpringBootstrap/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242150753,"owners_count":20080006,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-16T01:48:40.919Z","updated_at":"2026-05-27T13:31:09.276Z","avatar_url":"https://github.com/bbodi.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# KotlinReactSpringBootstrap\nA web application framework and structure template using Kotlin, React and Spring. It makes easier to start new projects from scratch.\n\nKotlin 1.0.0-beta-4589\n\n## Features:\n- Type safe React (thanks to [Reakt](https://github.com/andrewoma/reakt)) and [React Bootstrap](https://react-bootstrap.github.io/) builders\n\n   ```\nbsModalBody ({ closeButton = true }) {\n      bsRow {\n            bsCol({ md = 12 }) {\n                  form {\n                        bsRow {\n                              bsCol({ md = 6 }) {\n                                    bsInput(){}\n                              }\n                        }\n                  }\n            }\n      }\n}\n```\n- Typesafe HTML enums\n\n ```kotlin\nbsInput({type = InputType.Text}){...}\nbsButton ({bsStyle = BsStyle.Success}){}\n```\n- Typesafe element ID-s\n\n ```kotlin\nbsButton ({id = KeyValueScreenIds.addButton}) { text(\"Add\") }\n```\n- ... and helper methods for readable unit tests\n\n ```kotlin\nassertTrue(KeyValueScreenIds.addButton.appearOnScreen())\nKeyValueScreenIds.addButton.simulateClick()\nsimulateChangeInput(AccountScreenIds.modal.inputs.username) { input -\u003e\n       input.value = \"newUsername\"\n}\n```\n- Typesafe localization\n\n ```kotlin\n bsInput({ label = msg.screen.account.username })\n // or\n val accountScreenMsg = msg.screen.account\n bsInput({ label = accountScreenMsg.username })\n ```\n- Typesafe hash URL-s\n\n ```\nhref = \"#${Path.account.root}\"\n```\n- BDD frontend testing (inspired by [Spek](https://github.com/JetBrains/spek))\n\n ```kotlin\n    given(\"in any state\") {\n        on(\"routing to the KeyValue screen\") {\n            window.location.hash = Path.keyValue.root // these initialization codes run before every \"it\" invocations\n            it(\"should render KeyValue screen\") { assertTrue(jq(\"#${KeyValueScreenIds.screenId}\").size() == 1) }\n            it(\"should make the KeyValue menupoint active\") { assertTrue(jq(\"#${NavMenuIds.keyValue}\").parent().hasClass(\"active\")) }\n        }\n    }\n```\n- Router\n\n ```kotlin\nRouterStore.match(\n      \"${Path.login}\" to { params -\u003e\n            ...\n      },\n      \"${Path.keyValue.root}:id\" to { params -\u003e\n            assert(params[\"id\"] != null)\n      },\n      \"${Path.account.root}?id\" to { params -\u003e\n            // params[\"id\"] can be null\n      },\n      otherwise = {\n            ...\n      }\n)\n```\n- Frontend unit testing without any backend\n\n ```\nfile:///path_to/web_framework/frontend/tests.html?tests\n```\n- Authentication\n\n ```\nadmin, admin, ROLE_ADMIN\nuser, user, ROLE_USER\n```\n## Caveats / Hacks / Challanges\n- All the frontend dependency is included in the project, because the Kotlin Javascript and IntelliJ is not ready yet for conveniently handling dependencies.\n- At the frontend, asynchronous invocation is not rare, so unit tests must take into account that some state changes occur and become testable only after some time.   \n   It is solved by the special BDD syntax and QUnit's assert.async() call.  \n   \n ```kotlin\n private fun later(assert: dynamic, body: () -\u003e Unit) {  \n    val done = assert.async()  \n    window.setTimeout({  \n        body()  \n        done()  \n    }, 100)  \n }\n```  \n   The BDD builder collects all the \"given\", \"on\" and \"it\" bodies, and runs them synchronously, but with some delay between the state initialization (\"given\" and \"on\" bodies) and test (\"it\" bodies) codes.\n- Currently Kotlin generates QUnit tests from methods annotated with @Test. But in the @Test methods you cannot use the assert parameter of the QUnit test, which is necessary for asyncronous tests.  \nSo there is only one @Test method per class, which is necessary to run the test class automatically on startup, but in that test we call an other QUnit test method, in which we run our own BDD-style builders. This call only build a tree-like structure from the builder invocations, but we have to run these tests. We can do that by calling the runFirstGiven(assert) method.\n\n ```kotlin\n@native(\"QUnit.test\") fun qunitTest(name: String, body: (assert: dynamic)-\u003eUnit)\n```\n\n ```kotlin\n    @Test\n    fun hack() {\n        kotlin.test.assertTrue(true) // qunit hack, at least one assert must be present\n        qunitTest(\"KeyValueScreenTest\") { assert: dynamic -\u003e\n            tests() // it contains our given(...){} calls\n            runFirstGiven(assert)\n        }\n    }\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbbodi%2Fkotlinreactspringbootstrap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbbodi%2Fkotlinreactspringbootstrap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbbodi%2Fkotlinreactspringbootstrap/lists"}