MVU for Kotlin Multiplatform

Last update: May 16, 2022

Oolong

Build Status Maven Central Sonatype Nexus (Snapshots) License Slack chat

Oolong is an Elm inspired Model-View-Update (MVU) implementation for Kotlin multiplatform. As the name implies, three core concepts comprise the foundation of this architecture:

  • Model - a type to represent the program state

  • View - a function to map the state to view properties

  • Update - a function to update the state

By applying this simple pattern you can create composable, testable programs that can run on any platform. Oolong enables a common codebase for all platforms by using a render function which is implemented by each frontend.

Documentation

Get started with Oolong by reading the official guide.

Download

dependencies {
    implementation("org.oolong-kt:oolong:2.1.0")
}

GitHub

https://github.com/oolong-kt/oolong
Comments
  • 1. Remove ': Any' bounds in generic types

    Is your feature request related to a problem? Please describe.

    In Kotlin, we have the chance to have a compiler that makes safe to deal with nullability. Therefore, unlike in Java where null is very dangerous value that must be avoided at all cost, in Kotlin null is a valid and useful value to represent the absence of something. Yet the compiler will help us to make sure we treat it safely. On other words, the null of Kotlin is the equiavlent of Nothing in Elm: Useful and safe to use.

    Yet, many generic functions in oolong force the generic argument to be not null. Example: fun <A : Any, B : Any> map(effect: Effect<A>, f: (A) -> B): Effect<B>

    This adds an unecessary constraint on something that could have been safely nullable.

    It is also viral and will cause any helpers built on top to also add that generic boundary. Example:

    // Doesn't compile unless adding `: Any` bound to `T` and `R`
    fun <T, R> Effect<T>.map(transform: (T) -> R): Effect<R> = map(this, transform)
    

    By the way, as a side question: why not making map an extension function on Effect? It would be easier to discover and natural, since in Kotlin we're use to map over collections, sequences, flows, etc.

    I aggree, that it is probably very uncomon to use nullable types for model or messages. But, in a world of safe nullability, I don't see why it should completly be prevented by the framework. In elm for instance, one can freely use Maybe for model and messages.

    Describe the solution you'd like Remove uncessary : Any bound on generic arguments.

    Describe alternatives you've considered For a usage point of view, I can use Optional when I want deal with nullability in model or message. But it is not very idiomatic, we have nullability directly in the Kotlin type system.

    Reviewed by jcornaz at 2020-08-21 09:43
  • 2. [WIP] Add navigation component.

    Adds an abstraction over navigation which handles route changing, component delegation, and state caching. Example usage in the README.

    Let's discuss! @oolong-kt/developers

    Reviewed by pardom at 2020-06-12 23:04
  • 3. Support for js platform

    Hi, I wanted to test Oolong on JavaScript.

    I added the target and to implement runBlocking for the tests I removed the returned type. I also added `@JsName()' for test methods, the js platform doesn't support spaces in method names.

    I don't know if it is the good way to do it but I was able to play with Oolong :).

    I'm using Bulma and bulma-kotlin: Capture d’écran 2020-06-01 à 08 02 41

    Reviewed by jeancharles-roger at 2020-06-01 06:06
  • 4. Effect breaks Android Build

    Describe the bug Android application fails to build when "effect" is used

    To Reproduce I've made the following repo to demonstrate the issue - Oolong Test

    • "master" fails to build
    • "working" builds successfully because the "effect" code in Store.kt is commented out

    Additional context I'm using oolong-jvm because this is just going to run on Android and doesn't require using Kotlin Multi-Platform. I am unsure if that is related because everything else appears to work as expected

    Reviewed by dladukedev at 2019-11-07 02:30
  • 5. Documentation site alternatives

    Currently the project site is generated with GitBook. Let's investigate alternatives that allow more flexibility.

    Alternatives:

    • https://docusaurus.io
    • https://www.docz.site
    • https://docsify.js.org

    Please leave your suggestions below.

    Reviewed by pardom at 2019-04-12 14:10
  • 6. Bump mixin-deep from 1.3.1 to 1.3.2 in /oolong

    Bumps mixin-deep from 1.3.1 to 1.3.2.

    Commits
    Maintainer changes

    This version was pushed to npm by doowb, a new releaser for mixin-deep since your current version.


    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot ignore this [patch|minor|major] version will close this PR and stop Dependabot creating any more for this minor/major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    Reviewed by dependabot[bot] at 2020-01-07 21:21
  • 7. Bump handlebars from 4.1.2 to 4.5.3 in /oolong

    Bumps handlebars from 4.1.2 to 4.5.3.

    Changelog

    Sourced from handlebars's changelog.

    v4.5.3 - November 18th, 2019

    Bugfixes:

    • fix: add "no-prototype-builtins" eslint-rule and fix all occurences - f7f05d7
    • fix: add more properties required to be enumerable - 1988878

    Chores / Build:

    • fix: use !== 0 instead of != 0 - c02b05f
    • add chai and dirty-chai and sinon, for cleaner test-assertions and spies, deprecate old assertion-methods - 93e284e, 886ba86, 0817dad, 93516a0

    Security:

    • The properties __proto__, __defineGetter__, __defineSetter__ and __lookupGetter__ have been added to the list of "properties that must be enumerable". If a property by that name is found and not enumerable on its parent, it will silently evaluate to undefined. This is done in both the compiled template and the "lookup"-helper. This will prevent new Remote-Code-Execution exploits that have been published recently.

    Compatibility notes:

    • Due to the security-fixes. The semantics of the templates using __proto__, __defineGetter__, __defineSetter__ and __lookupGetter__ in the respect that those expression now return undefined rather than their actual value from the proto.
    • The semantics have not changed in cases where the properties are enumerable, as in:
    {
      __proto__: 'some string'
    }
    
    • The change may be breaking in that respect, but we still only increase the patch-version, because the incompatible use-cases are not intended, undocumented and far less important than fixing Remote-Code-Execution exploits on existing systems.

    Commits

    v4.5.2 - November 13th, 2019

    Bugfixes

    • fix: use String(field) in lookup when checking for "constructor" - d541378
    • test: add fluent API for testing Handlebars - c2ac79c

    Compatibility notes:

    • no incompatibility are to be expected
    ... (truncated)
    Commits
    • c819c8b v4.5.3
    • 827c9d0 Update release notes
    • f7f05d7 fix: add "no-prototype-builtins" eslint-rule and fix all occurences
    • 1988878 fix: add more properties required to be enumerable
    • 886ba86 test/chore: add chai/expect and sinon to "runtime"-environment
    • 0817dad test: add sinon as global variable to eslint in the specs
    • 93516a0 test: add sinon.js for spies, deprecate current assertions
    • 93e284e chore: add chai and dirty-chai for better test assertions
    • c02b05f fix: use !== 0 instead of != 0
    • 8de121d v4.5.2
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot ignore this [patch|minor|major] version will close this PR and stop Dependabot creating any more for this minor/major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    Reviewed by dependabot[bot] at 2019-12-28 05:16
  • 8. Effect batch is not asynchronous

    Currently, Effect functions are suspended, however this does not prevent them from blocking when combined with batch. The batch function iterates over and calls each effect. Given the current implementation, each Effect will block the iteration until completed:

    typealias Effect<Msg> = suspend (dispatch: Dispatch<Msg>) -> Any?
    
    fun <Msg> batch(effects: Iterable<Effect<Msg>>): Effect<Msg> =
        { dispatch -> for (effect in effects) effect(dispatch) }
    

    Instead, we should define Effect in the context of a CoroutineScope and launch each Effect as we iterate over them.

    typealias Effect<Msg> = suspend CoroutineScope.(dispatch: Dispatch<Msg>) -> Any?
    
    fun <Msg> batch(effects: Iterable<Effect<Msg>>): Effect<Msg> =
        { dispatch -> for (effect in effects) launch { effect(dispatch) } }
    
    Reviewed by pardom at 2019-04-18 18:57
  • 9. Bump pygments from 2.6.1 to 2.7.4 in /.github/workflows

    Bumps pygments from 2.6.1 to 2.7.4.

    Release notes

    Sourced from pygments's releases.

    2.7.4

    • Updated lexers:

      • Apache configurations: Improve handling of malformed tags (#1656)

      • CSS: Add support for variables (#1633, #1666)

      • Crystal (#1650, #1670)

      • Coq (#1648)

      • Fortran: Add missing keywords (#1635, #1665)

      • Ini (#1624)

      • JavaScript and variants (#1647 -- missing regex flags, #1651)

      • Markdown (#1623, #1617)

      • Shell

        • Lex trailing whitespace as part of the prompt (#1645)
        • Add missing in keyword (#1652)
      • SQL - Fix keywords (#1668)

      • Typescript: Fix incorrect punctuation handling (#1510, #1511)

    • Fix infinite loop in SML lexer (#1625)

    • Fix backtracking string regexes in JavaScript/TypeScript, Modula2 and many other lexers (#1637)

    • Limit recursion with nesting Ruby heredocs (#1638)

    • Fix a few inefficient regexes for guessing lexers

    • Fix the raw token lexer handling of Unicode (#1616)

    • Revert a private API change in the HTML formatter (#1655) -- please note that private APIs remain subject to change!

    • Fix several exponential/cubic-complexity regexes found by Ben Caller/Doyensec (#1675)

    • Fix incorrect MATLAB example (#1582)

    Thanks to Google's OSS-Fuzz project for finding many of these bugs.

    2.7.3

    ... (truncated)

    Changelog

    Sourced from pygments's changelog.

    Version 2.7.4

    (released January 12, 2021)

    • Updated lexers:

      • Apache configurations: Improve handling of malformed tags (#1656)

      • CSS: Add support for variables (#1633, #1666)

      • Crystal (#1650, #1670)

      • Coq (#1648)

      • Fortran: Add missing keywords (#1635, #1665)

      • Ini (#1624)

      • JavaScript and variants (#1647 -- missing regex flags, #1651)

      • Markdown (#1623, #1617)

      • Shell

        • Lex trailing whitespace as part of the prompt (#1645)
        • Add missing in keyword (#1652)
      • SQL - Fix keywords (#1668)

      • Typescript: Fix incorrect punctuation handling (#1510, #1511)

    • Fix infinite loop in SML lexer (#1625)

    • Fix backtracking string regexes in JavaScript/TypeScript, Modula2 and many other lexers (#1637)

    • Limit recursion with nesting Ruby heredocs (#1638)

    • Fix a few inefficient regexes for guessing lexers

    • Fix the raw token lexer handling of Unicode (#1616)

    • Revert a private API change in the HTML formatter (#1655) -- please note that private APIs remain subject to change!

    • Fix several exponential/cubic-complexity regexes found by Ben Caller/Doyensec (#1675)

    • Fix incorrect MATLAB example (#1582)

    Thanks to Google's OSS-Fuzz project for finding many of these bugs.

    Version 2.7.3

    (released December 6, 2020)

    ... (truncated)

    Commits
    • 4d555d0 Bump version to 2.7.4.
    • fc3b05d Update CHANGES.
    • ad21935 Revert "Added dracula theme style (#1636)"
    • e411506 Prepare for 2.7.4 release.
    • 275e34d doc: remove Perl 6 ref
    • 2e7e8c4 Fix several exponential/cubic complexity regexes found by Ben Caller/Doyensec
    • eb39c43 xquery: fix pop from empty stack
    • 2738778 fix coding style in test_analyzer_lexer
    • 02e0f09 Added 'ERROR STOP' to fortran.py keywords. (#1665)
    • c83fe48 support added for css variables (#1633)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    Reviewed by dependabot[bot] at 2021-04-29 13:40
  • 10. Deprecate type aliases

    The type aliases for incoming types obscure the underlying types making it difficult to comprehend the expected shape of functions. Similar to Elm, we should prefer the underlying type.

    Reviewed by pardom at 2020-09-10 13:39
  • 11. Bump mkdocs from 1.1.2 to 1.2.3 in /.github/workflows

    Bumps mkdocs from 1.1.2 to 1.2.3.

    Release notes

    Sourced from mkdocs's releases.

    1.2.3

    MkDocs 1.2.3 is a bugfix release for MkDocs 1.2.

    Aside: MkDocs has a new chat room on Gitter/Matrix. More details.

    Improvements:

    • Built-in themes now also support these languages:

    • Third-party plugins will take precedence over built-in plugins with the same name (#2591)

    • Bugfix: Fix ability to load translations for some languages: core support (#2565) and search plugin support with fallbacks (#2602)

    • Bugfix (regression in 1.2): Prevent directory traversal in the dev server (#2604)

    • Bugfix (regression in 1.2): Prevent webserver warnings from being treated as a build failure in strict mode (#2607)

    • Bugfix: Correctly print colorful messages in the terminal on Windows (#2606)

    • Bugfix: Python version 3.10 was displayed incorrectly in --version (#2618)

    Other small improvements; see commit log.

    1.2.2

    MkDocs 1.2.2 is a bugfix release for MkDocs 1.2 -- make sure you've seen the "major" release notes as well.

    • Bugfix (regression in 1.2): Fix serving files/paths with Unicode characters (#2464)

    • Bugfix (regression in 1.2): Revert livereload file watching to use polling observer (#2477)

      This had to be done to reasonably support usages that span virtual filesystems such as non-native Docker and network mounts.

      This goes back to the polling approach, very similar to that was always used prior, meaning most of the same downsides with latency and CPU usage.

    • Revert from 1.2: Remove the requirement of a site_url config and the restriction on use_directory_urls (#2490)

    • Bugfix (regression in 1.2): Don't require trailing slash in the URL when serving a directory index in mkdocs serve server (#2507)

      Instead of showing a 404 error, detect if it's a directory and redirect to a path with a trailing slash added, like before.

    • Bugfix: Fix gh_deploy with config-file in the current directory (#2481)

    • Bugfix: Fix reversed breadcrumbs in "readthedocs" theme (#2179)

    • Allow "mkdocs.yaml" as the file name when '--config' is not passed (#2478)

    ... (truncated)

    Commits
    • d167eab Release 1.2.3 (#2614)
    • 5629b09 Re-format translation files to pass a lint check (#2621)
    • 2c4679b Re-format translation files to pass a lint check (#2620)
    • 9262cc5 Fix the code to abbreviate Python's version (#2618)
    • 8345850 Add hint about -f/--config-file in configuration documentation (#2616)
    • 815af48 Added translation for Brazilian Portuguese (#2535)
    • 6563439 Update contact instructions: announce chat, preference for issues (#2610)
    • 6b72eef We can again announce support of zh_CN locale (#2609)
    • b18ae29 Drop assert_mock_called_once compat method from tests (#2611)
    • 7a27572 Isolate strict warning counter to just the ongoing build (#2607)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    Reviewed by dependabot[bot] at 2022-05-16 18:21
  • 12. Consider alternative type and syntax for Next

    Is your feature request related to a problem? Please describe.

    I brought this up in Slack but would like to continue the conversation here to open it to other folks that would like to participate.

    The Next type is currently typealias'd to a Pair<Model, Effect<Msg>>. The usage of Pair comes from the desire to use the built in tuple types that the Kotlin language offers via generics and data class (Pair and Triple).

    Unfortunately, unlike Elm's tuples which have a nice syntax for creation with parentheses (e.g. (1, 2, "a", "b")), Kotlin relies on constructors for its data classes with no short-hand replacement. To work around that, the language offers an infix function to to aid in Pair's creation.

    This leads to idiomatic Oolong code in the Update/Init functions looking somewhat like this:

    val update: Update<Msg, Model> = { msg, model ->
      model to none()
    }
    

    This syntax can be a little hard to decipher, especially as a novice reader of the code. It requires some knowledge of the Oolong type definitions to understand why this syntax is being used. The keyword to reads more like a mapping than a union (to me, at least), and I think there's an opportunity here to be more explicit with types and have a more readable syntax.

    Describe the solution you'd like

    Give an explicit type to Next and provide a more ergonomic infix operator for its creation to lean in to the Kotlin language features and tools.

    Two steps to this solution:

    1. Redefine Next to data class Next<Model, Msg>(val model: Model, val effect: Effect<Msg>)
    2. Add a new infix function and: infix fun <Model, Msg> Model.and(effect: Effect<Msg>) = Next(this, effect)

    This changes our above example to read like this:

    val update: Update<Msg, Model> = { msg, model ->
        model and none()
    }
    

    Advantages:

    • the code reads as "return the updated model and these effects", which I think is a very nice improvement
    • extensions on Next will not pollute the Pair type in case there were extensions that were Oolong-specific
    • deconstructing the Next type will have named fields instead of first and second

    Cons:

    • lose access to any extensions on Pair
    • potentially breaking change to the type system

    note: I'd expect that we provide a to infix for compatibility initially, but have that deprecated

    @Deprecated(
        message = "prefer `and` operator, `to` will be removed in a future update",
        replaceWith = ReplaceWith("this.and(effect)")
    )
    infix fun <Model, Msg> Model.to(effect: Effect<Msg>) = Next(this, effect)
    

    The problem that this doesn't solve is the syntax for the optional Effect case, I think ideally you'd be able to have a syntax that supports returning just the model or returning the model and effects, e.g.

    val update: Update<Msg, Model> = { msg, model ->
        model
    }
    

    Not sure what might be available for that solution (outside of a compiler plugin that allows for a more ergonomic tuple creation syntax)

    Describe alternatives you've considered

    • with would be an acceptable alternative to and but it is already a reserved word in the Kotlin language
    • I opted against an infix operator (e.g. *) since that is not a standard Kotlin language feature and would likely be considered a bit obtuse in the way that to is today with the added negative of being less discoverable

    Additional context

    none

    Reviewed by sddamico at 2020-09-01 17:52
  • 13. Subscription support

    Is your feature request related to a problem? Please describe.

    I want to subscribe to some events, that might be external to my system. Example:

    • Get an event every X seconds
    • Subscribe to events from a websocket

    Describe the solution you'd like

    Since the present library is inspired from elm, I'd find natural to imitate elm's subscription system (in Browser.element).

    That could be translated in Kotlin like this:

    data class Model(val ticks: Int = 0)
    sealed class Msg {
      object Tick : Msg()
    }
    
    val subscribe = Subscribe<Model, Msg> { model ->
      every(10.seconds).map { Msg.Tick }
    }
    
    // ...
    
    val dispose = Oolong.runtime(
        init,
        update,
        suscribe,
        view,
        render
    )
    

    Of course this is only a draft example, and any variation of the API would do.

    Describe alternatives you've considered

    I think I could start a coroutine from a disposable effect that will call dispatch to fire the messages.

    That would however require me to keep an instance of the dispose in my model, so that I can cancel it later.

    Reviewed by jcornaz at 2020-07-17 15:53
  • 14. Flipper Plugin

    Related links:

    • https://fbflipper.com/
    • https://fbflipper.com/docs/extending/index.html

    Please follow up with suggestions and ideas if you have them, @oolong-kt/developers.

    Reviewed by pardom at 2020-04-10 14:15
Model-View-ViewModel architecture components for mobile (android & ios) Kotlin Multiplatform development
Model-View-ViewModel architecture components for mobile (android & ios) Kotlin Multiplatform development

Mobile Kotlin Model-View-ViewModel architecture components This is a Kotlin Multiplatform library that provides architecture components of Model-View-

May 17, 2022
Extendable MVI framework for Kotlin Multiplatform with powerful debugging tools (logging and time travel), inspired by Badoo MVICore library
Extendable MVI framework for Kotlin Multiplatform with powerful debugging tools (logging and time travel), inspired by Badoo MVICore library

Should you have any questions or ideas please welcome to the Slack channel: #mvikotlin Inspiration This project is inspired by Badoo MVICore library.

May 17, 2022
Redux implementation for Kotlin (supports multiplatform JVM, native, JS, WASM)

Redux-Kotlin ![badge][badge-ios] A redux standard for Kotlin that supports multiplatform projects. Full documentation at http://reduxkotlin.org. Misso

May 16, 2022
Unidirectional Data Flow in Kotlin - Port of https://github.com/ReSwift/ReSwift to Kotlin
Unidirectional Data Flow in Kotlin - Port of https://github.com/ReSwift/ReSwift to Kotlin

ReKotlin Port of ReSwift to Kotlin, which corresponds to ReSwift/4.0.0 Introduction ReKotlin is a Redux-like implementation of the unidirectional data

May 11, 2022
MVVM RECIPE ANDROID APP Is an app where I show how to use MVVM, retrofit, dagger hilt, coroutine, liveData, Kotlin, navigation component, and so on...
MVVM RECIPE ANDROID APP Is an app where I show how to use MVVM, retrofit, dagger hilt, coroutine, liveData, Kotlin, navigation component, and so on...

MVVM RECIPE ANDROID APP Is an app where I show how to use MVVM, retrofit, dagger hilt, coroutine, liveData, kotlin, navigation component, and so on...

Apr 4, 2022
A sample project in Kotlin to demonstrate AndroidX, MVVM, Coroutines, Hilt, Room, Data Binding, View Binding, Retrofit, Moshi, Leak Canary and Repository pattern.

This repository contains a sample project in Kotlin to demonstrate AndroidX, MVVM, Coroutines, Hilt, Room, Data Binding, View Binding, Retrofit, Moshi, Leak Canary and Repository pattern

May 9, 2022
Android Clean Architecture💎 Base Project Android with Kotlin and MVVM applying clean architecture
 Android Clean Architecture💎 Base Project Android with Kotlin and MVVM applying clean architecture

Android Clean Architecture?? Base Project Android with Kotlin and MVVM applying clean architecture

May 18, 2022
A sample to showcase Kotlin, MVVM, Koin, Coroutines, StateFlow, Room, WorkManager, Retrofit and Unit test.

TVMaze-Cache A sample to showcase Kotlin, MVVM, Koin, Coroutines, StateFlow, Room, WorkManager, Retrofit and Unit test. Features MVVM Architecture + R

Mar 13, 2022
📒Note taking app, MVVM with Google Architectural components Room, LiveData and ViewModel written in Kotlin, androidx libraries
📒Note taking app, MVVM with Google Architectural components Room, LiveData and ViewModel written in Kotlin, androidx libraries

?? MyNotes Note taking Android App using androidx libraries, MVVM with Google Architectural components Room, LiveData and ViewModel. Written in Kotlin

May 1, 2022
simple app used Kotlin MVVM Dagger2 Room Coroutines Retrofit2

Exhibits Application which retrieves data from Webserver (via Retrofit), saves it into Room and get from it if user is offline. There are applying MVV

Oct 14, 2021
Clean Architecture - Kotlin, MVVM, Use cases
Clean Architecture - Kotlin, MVVM, Use cases

CleanArchitecture Is Clean Architecture only MVVM ? NO, MVVM is a part of clean architecture. MVVM includes Model, View and ViewModel and in addition

May 13, 2022
Kotlin+Flow+Retrofit+OKHttp+ViewBanding+ViewModel+LiveData封装的一个Kotlin版本的MVVM框架

Gitee 地址:kmvvm Github 地址:kmvvm CHANGE LOG 技术要点 支持Flow+Retrofit+OkHttp实现链式http请求 支持Rxjava+Retrofit+OkHttp实现链式http请求 封装基类:BaseActivity、BaseVMActivity、Ba

May 23, 2022
Ceci est une application d'actualités de l'architecture MVVM avec Kotlin
Ceci est une application d'actualités de l'architecture MVVM avec Kotlin

MVVM-Appli Infos Ceci est une application d'actualités de l'architecture MVVM avec Kotlin utilisant des composants : Retrofit, Room, Coroutines, et Na

Nov 4, 2021
An android app built using Kotlin following Multi-Module Clean Architecture MVVM
An android app built using Kotlin following Multi-Module Clean Architecture MVVM

RickyandMorty An android app built using Kotlin that consumes RickyadMorty API to display characters.It has been built following Clean Architecture Pr

Feb 3, 2022
JeTaxi is built on Clean Architecture-MVVM with Kotlin and follows modern android development trends.
 JeTaxi is built on Clean Architecture-MVVM with Kotlin and follows modern android development trends.

JeTaxi is built on Clean Architecture-MVVM with Kotlin and follows modern android development trends. Also, It uses some of Jetpack and popular libraries. These are Kotlin Coroutine-Flow, kotlinx.serialization, Hilt, Compose, Accompanist, Retrofit2, OkHttp3, Chucker, MockWebServer, Truth.

Mar 7, 2022
Make E-Commerce using Kotlin MVVM
Make E-Commerce using Kotlin MVVM

Kotlin E-Commerce MVVM Make E-Commerce using Kotlin, and for backend i use Golang, and PHP Feature MVVM Retrofit2 15+ Screen Payment Gateway (Razorpay

Feb 21, 2022
App kotlin with flow, paging 3, MVVM, Room, Dagger hilt

TMDBTest App kotlin with flow, paging 3, MVVM, Room, Dagger hilt Para compilar la app se tiene que descargar el proyecto. Luego poner la APIKEY de TMD

Feb 22, 2022
MVVM Kotlin Android Architecture
MVVM Kotlin Android Architecture

Model-View-ViewModel (ie MVVM) Model-View-ViewModel (ie MVVM) is a template of a client application architecture, proposed by John Gossman as an alter

Mar 13, 2022
MVVM Android Studio Kotlin Project Dog Images
MVVM Android Studio Kotlin Project Dog Images

MVVM Android Studio Kotlin Project Dog Images This project implement: MVVM Retro

Apr 17, 2022