<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/flattening-my-dependency-graph-3cchomhzt" -->

---
title: Flattening my Dependency Graph | daily.dev
description: A developer shares how he restructured the module dependency graph of a Kotlin server project called Rounds, which uses SQLDelight, WebAuthn4J, kotlinx.html,...
canonical: https://daily.dev/posts/flattening-my-dependency-graph-3cchomhzt
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Flattening my Dependency Graph | daily.dev
og:description: A developer shares how he restructured the module dependency graph of a Kotlin server project called Rounds, which uses SQLDelight, WebAuthn4J, kotlinx.html,...
og:url: https://daily.dev/posts/flattening-my-dependency-graph-3cchomhzt
og:image: https://api.daily.dev/og/posts/3CchomHzt.png
og:image:alt: Flattening my Dependency Graph
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Flattening my Dependency Graph

**[Square](https://daily.dev/sources/publicobject)** · 4 min read · 1 upvotes · 1 comments

## Summary

A developer shares how he restructured the module dependency graph of a Kotlin server project called Rounds, which uses SQLDelight, WebAuthn4J, kotlinx.html, and Ktor. He describes the tradeoffs of having too few versus too many modules, then applies a scheme from Ralf Wondratschek used at Square that splits each feature into api and real (implementation) modules, forbidding cross-feature dependencies on implementation code. To eliminate remaining dependency chains between api modules caused by shared typesafe ID classes, he extracts a new identifiers module containing only those value objects, flattening the graph so all real modules build in parallel.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://publicobject.com/2026/02/03/flattening-my-dependency-graph>

## Questions this post answers

### How can I avoid dependency cycles between api modules in a modular Kotlin project?

Extract shared typesafe ID classes into a separate, dependency-free module (for example, an identifiers module) that all api modules depend on directly. This removes the need for one api module to depend on another just to reference an ID type like AccountId or PasskeyId, eliminating arbitrary ordering decisions and breaking sequential build chains between api modules.

_Developers wrestling with module boundaries can find more real-world architecture patterns like this on daily.dev._

### What is Ralf Wondratschek's module pattern used at Square for Android?

It splits each feature into three modules: public, holding API interfaces and value objects; impl, holding implementation classes; and impl-wiring, holding dependency injection glue connecting public interfaces to impl classes. A strict rule forbids modules from depending on each other's impl or impl-wiring modules, so they can only depend on public, letting implementation modules build in parallel with better build cache hits.

_Teams evaluating module decomposition strategies can track patterns like this via daily.dev._

## Similar posts on daily.dev

- [How Horizontal Clean Architecture Created a Room Dependency Problem](https://daily.dev/posts/how-horizontal-clean-architecture-created-a-room-dependency-problem-mtlowwntj) · Medium · 0 upvotes · 0 comments
- [Android Modularization That Holds Up: 5 Lessons for Large Codebases](https://daily.dev/posts/android-modularization-that-holds-up-5-lessons-for-large-codebases-1tagym5g1) · ProAndroidDev · 0 upvotes · 0 comments
- [Multi-Module Build Economics: Designing API vs. Implementation Boundaries to Survive 50\+ Dev Teams](https://daily.dev/posts/multi-module-build-economics-designing-api-vs-implementation-boundaries-to-survive-50-dev-teams-eboehzqc9) · Medium · 1 upvotes · 0 comments
- [Building Modular Monoliths With Kotlin and Spring](https://daily.dev/posts/building-modular-monoliths-with-kotlin-and-spring-asye43aco) · JetBrains · 0 upvotes · 0 comments
- [Modularizing at Scale: How Halodoc Adopted Android Dynamic Feature Modules](https://daily.dev/posts/modularizing-at-scale-how-halodoc-adopted-android-dynamic-feature-modules-jpfwssyu8) · Halodoc · 0 upvotes · 0 comments

---

Tags: [#architecture](https://daily.dev/tags/architecture), [#kotlin](https://daily.dev/tags/kotlin), [#dependency-injection](https://daily.dev/tags/dependency-injection), [#gradle](https://daily.dev/tags/gradle)

[View this post on daily.dev](https://daily.dev/posts/flattening-my-dependency-graph-3cchomhzt)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Flattening my Dependency Graph","url":"https://daily.dev/posts/flattening-my-dependency-graph-3cchomhzt","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/flattening-my-dependency-graph-3cchomhzt"},"datePublished":"2026-08-23T12:18:48.931Z","dateModified":"2026-09-14T08:25:25.572Z","description":"A developer shares how he restructured the module dependency graph of a Kotlin server project called Rounds, which uses SQLDelight, WebAuthn4J, kotlinx.html,...","image":"https://media.daily.dev/image/upload/s--P4t4XyoV--/f_auto/v1722860399/public/Placeholder%2001","thumbnailUrl":"https://media.daily.dev/image/upload/s--P4t4XyoV--/f_auto/v1722860399/public/Placeholder%2001","isAccessibleForFree":true,"articleSection":"Square","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Square","logo":"https://media.daily.dev/image/upload/s--QZPKZNBW--/f_auto,q_auto/v1787487457/logos/publicobject?_a=BAMAMicg0","url":"https://daily.dev/sources/publicobject"},"commentCount":1,"discussionUrl":"https://daily.dev/posts/flattening-my-dependency-graph-3cchomhzt","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":1}],"keywords":"architecture,kotlin,dependency-injection,gradle","timeRequired":"PT4M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Square","item":"https://daily.dev/sources/publicobject"},{"@type":"ListItem","position":3,"name":"Flattening my Dependency Graph"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/flattening-my-dependency-graph-3cchomhzt#faq","mainEntity":[{"@type":"Question","name":"How can I avoid dependency cycles between api modules in a modular Kotlin project?","acceptedAnswer":{"@type":"Answer","text":"Extract shared typesafe ID classes into a separate, dependency-free module (for example, an identifiers module) that all api modules depend on directly. This removes the need for one api module to depend on another just to reference an ID type like AccountId or PasskeyId, eliminating arbitrary ordering decisions and breaking sequential build chains between api modules. Developers wrestling with module boundaries can find more real-world architecture patterns like this on daily.dev."}},{"@type":"Question","name":"What is Ralf Wondratschek's module pattern used at Square for Android?","acceptedAnswer":{"@type":"Answer","text":"It splits each feature into three modules: public, holding API interfaces and value objects; impl, holding implementation classes; and impl-wiring, holding dependency injection glue connecting public interfaces to impl classes. A strict rule forbids modules from depending on each other's impl or impl-wiring modules, so they can only depend on public, letting implementation modules build in parallel with better build cache hits. Teams evaluating module decomposition strategies can track patterns like this via daily.dev."}}]}
```

