# inclusive

Published articles for inclusive.

This is one page of public article previews, not the complete archive. Follow Next page to continue. Summaries are not the original full articles.

## Designing Claude for ears, not eyes: An accessibility skill for blind and low-vision users

DevFeed: [Designing Claude for ears, not eyes: An accessibility skill for blind and low-vision users](<https://devfeed.tech/articles/designing-claude-for-ears-not-eyes-an-accessibility-skill-for-blind-and-low-vision-users-38847.md>)

Original publisher: [Read original article](<https://building.nubank.com/designing-claude-for-ears-not-eyes-an-accessibility-skill-for-blind-and-low-vision-users/>)

Author: Nubank Editorial

Published: 2026-09-16T14:09:16Z

Content type: article

Language: en

Sources: [Nubank](<https://devfeed.tech/sources/nubank.md>)

Topics: [Accessibility](<https://devfeed.tech/topics/accessibility.md>), [Claude](<https://devfeed.tech/topics/claude.md>), [User interface design](<https://devfeed.tech/topics/ui-design.md>), [screen](<https://devfeed.tech/topics/screen.md>), [Users](<https://devfeed.tech/topics/users.md>), [Development](<https://devfeed.tech/topics/development.md>)

Tags: [accessibility](<https://devfeed.tech/tags/accessibility.md>), [accessible](<https://devfeed.tech/tags/accessible.md>), [claude](<https://devfeed.tech/tags/claude.md>), [culture-values](<https://devfeed.tech/tags/culture-values.md>), [data-science-machine-learning](<https://devfeed.tech/tags/data-science-machine-learning.md>), [development-environment](<https://devfeed.tech/tags/development-environment.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [life-at-nu](<https://devfeed.tech/tags/life-at-nu.md>), [people-with-disabilities](<https://devfeed.tech/tags/people-with-disabilities.md>), [text](<https://devfeed.tech/tags/text.md>), [users](<https://devfeed.tech/tags/users.md>), [vision](<https://devfeed.tech/tags/vision.md>)

### AI overview

Nubank describes BLIND-CLAUDE.md, an instruction set that adapts Claude responses for people who primarily use screen readers or read-aloud functionality. The approach treats auditory comprehension as an engineering constraint and changes behavioral instructions without modifying Claude or adding a native accessibility feature.

### Source excerpt

How a cognitively diverse IT team at Nubank, they coded screen reader-friendly rules into Claude's instructions, treating auditory comprehension as an engineering constraint The post Designing Claude for ears, not eyes: An accessibility skill for blind and low-vision users appeared first on Building Nubank.

## Hackathons Can Be Healthy

DevFeed: [Hackathons Can Be Healthy](<https://devfeed.tech/articles/hackathons-can-be-healthy-27380.md>)

Original publisher: [Read original article](<http://engineering.khanacademy.org/posts/healthy-hackathons.htm>)

Author: Khan Academy

Published: 2016-07-11T22:00:00Z

Content type: opinion

Language: en

Sources: [Khan Academy](<https://devfeed.tech/sources/khan-academy.md>)

Topics: [Hackathon](<https://devfeed.tech/topics/hackathon.md>), [Learning](<https://devfeed.tech/topics/learning.md>), [Open Source](<https://devfeed.tech/topics/open-source.md>)

Tags: [eng-leads](<https://devfeed.tech/tags/eng-leads.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [hackathon](<https://devfeed.tech/tags/hackathon.md>), [hackathons](<https://devfeed.tech/tags/hackathons.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [learning](<https://devfeed.tech/tags/learning.md>), [news](<https://devfeed.tech/tags/news.md>), [open-source](<https://devfeed.tech/tags/open-source.md>)

### AI overview

Khan Academy describes its twice-yearly internal hackathons and the benefits of collaboration, creativity, team bonding, morale, and learning. The article also explains how the company adapted its hackathon format to be more inclusive, sustainable, and healthy.

### Source excerpt

By Tom Yedwab As an organization whose raison d'être is learning - we in fact have a campaign ... Read more

## Android's Agentic APIs, App Integration, and Agent Distribution

DevFeed: [Android's Agentic APIs, App Integration, and Agent Distribution](<https://devfeed.tech/articles/android-s-ai-era-hype-vs-architecture-26157.md>)

Original publisher: [Read original article](<https://dev.to/tkuenneth/androids-ai-era-hype-vs-architecture-13kf>)

Author: Thomas Künneth

Published: 2026-09-12T12:42:56Z

Content type: opinion

Language: en

Sources: [Thomas Künneth](<https://devfeed.tech/sources/thomas-kunneth.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [Artificial Intelligence](<https://devfeed.tech/topics/ai.md>), [Operating system](<https://devfeed.tech/topics/operating-system.md>), [Automation](<https://devfeed.tech/topics/automation.md>), [API](<https://devfeed.tech/topics/api.md>)

Tags: [ai](<https://devfeed.tech/tags/ai.md>), [android](<https://devfeed.tech/tags/android.md>), [apis](<https://devfeed.tech/tags/apis.md>), [architecture](<https://devfeed.tech/tags/architecture.md>), [automation](<https://devfeed.tech/tags/automation.md>), [code](<https://devfeed.tech/tags/code.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [google](<https://devfeed.tech/tags/google.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [mobiledev](<https://devfeed.tech/tags/mobiledev.md>), [os](<https://devfeed.tech/tags/os.md>), [software](<https://devfeed.tech/tags/software.md>)

### AI overview

This commentary examines Android's shift toward an intelligent system through three layers: on-device model runtimes and API stability, app integration with agents, and agent distribution. It argues that Google's platform messaging combines distinct engineering claims and that some agent capabilities remain less mature than the marketing suggests.

### Source excerpt

I have spent the last year and a half building against Android's agentic APIs, not reading about them from a keynote seat. Be nice got an AppFunction so Gemini could invoke createAppPair directly; a few months later, bumping a single alpha broke it, because alpha10 quietly stopped shipping the service component alpha08 depended on. That scar tissue is a decent filter for keynote language. So when Android's president, Sameer Samat, describes the platform moving from an operating system to an intelligent system, I try not to start with whether that's true. I start with which layer of the stack that sentence is describing, because "Intelligence System" covers at least three very different things at once, and only one of them is finished enough to build on. Three Claims Wearing One Name Layer one is the model runtime: what executes on the device, which APIs call it, how stable those APIs are. Layer two is app integration: how an app exposes itself to an agent, and how much of that exposure the app developer controls versus how much Android does for them without asking. Layer three is distribution: who gets to be the agent standing in front of the user, and whether that's a genuinely open contest or a foregone one. Google's own framing blurs all three into a single narrative arc. The February 2026 "Intelligent OS" post redefined what success means for an app: not opens, but completed tasks, with or without a human touching the UI. Android's May I/O recap made the platform claim explicit: agents like Gemini can already "complete task automation" on Android, navigating an app on the user's behalf without anyone tapping through it themselves. One sentence, three separate engineering claims bundled together. I want to pull them apart in the order I trust them least to most, which also happens to be the order in which the marketing runs furthest ahead of the shipping code. Layer Three First, Because It's the Weakest: Who Gets to Be the Agent Start with distribution, since tha

## Dealing with sensitive permissions on Android

DevFeed: [Dealing with sensitive permissions on Android](<https://devfeed.tech/articles/dealing-with-sensitive-permissions-on-android-26161.md>)

Original publisher: [Read original article](<https://dev.to/tkuenneth/dealing-with-sensitive-permissions-on-android-3icg>)

Author: Thomas Künneth

Published: 2026-09-05T09:22:30Z

Content type: opinion

Language: en

Sources: [Thomas Künneth](<https://devfeed.tech/sources/thomas-kunneth.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [Google Play](<https://devfeed.tech/topics/google-play.md>), [Authorization](<https://devfeed.tech/topics/authorization.md>), [Google](<https://devfeed.tech/topics/google.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [app](<https://devfeed.tech/tags/app.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [google-play](<https://devfeed.tech/tags/google-play.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [permission](<https://devfeed.tech/tags/permission.md>), [policy](<https://devfeed.tech/tags/policy.md>), [privacy](<https://devfeed.tech/tags/privacy.md>), [software](<https://devfeed.tech/tags/software.md>)

### AI overview

This article explains how Android and Google Play treat READ_CALL_LOG as a sensitive permission. It describes how Google Play restrictions affected TKWeek's distribution and led the author to remove call-log access from Play builds while restoring the feature in builds distributed through F-Droid and Obtainium.

### Source excerpt

Right now the developer community seems fascinated (if not outright obsessed) with agentic coding. That wave is real, and it will heavily impact how we build software. But let's not forget there are other topics worth attention. Here, the focus is something less fashionable: sensitive permissions on Android. After shipping TKWeek updates outside Google Play and answering the inevitable Why isn't this on the Play Store? with a blunt Sensitive permissions, it is fair to ask whether that topic still matters in 2026. I can answer that from shipping one app for a long time. I started working on TKWeek back in 2010. Some time later I added a module called My day that shows important information for a particular day, including missed phone calls. READ_CALL_LOG is a dangerous permission since API level 23, so users who do not want to allow the app to read those details have a secure, reliable safety hatch. Still, after a late-2018 announcement, by 2019 Google Play was enforcing READ_CALL_LOG under its high-risk / sensitive rules. Now, what does that store layer mean anyway? Dangerous on the device, sensitive in the store On the platform side, Android already classifies quite a few permissions as dangerous: they guard private user data, and starting with API 23 the user must grant them at runtime. READ_CALL_LOG is in that bucket (Manifest.permission.READ_CALL_LOG). Google Play's extra layer sits on top of that. In Play docs the umbrella is high-risk or sensitive permissions; Call Log and SMS are restricted permission groups. Either way, it is store policy, not just OS protection. For Call Log and SMS, only narrow use cases are allowed (typically default Phone, SMS, or Assistant handlers, plus a short list of exceptions), and you must declare them in Play Console or remove them from the manifest. See Google's Permissions and APIs that Access Sensitive Information and Use of SMS or Call Log permission groups. Back in 2021 that policy stopped being theoretical. Showing missed c

## Reproducible Builds summit 2026 to take place in Gothenburg

DevFeed: [Reproducible Builds summit 2026 to take place in Gothenburg](<https://devfeed.tech/articles/reproducible-builds-summit-2026-to-take-place-in-gothenburg-34162.md>)

Original publisher: [Read original article](<https://reproducible-builds.org/news/2026/08/12/reproducible-builds-summit-in-gothenburg/>)

Published: 2026-08-12T00:00:00Z

Content type: news

Language: en

Sources: [reproducible-builds.org](<https://devfeed.tech/sources/reproducible-builds-org.md>)

Topics: [reproducible builds](<https://devfeed.tech/topics/reproducible-builds.md>), [builds](<https://devfeed.tech/topics/builds.md>)

Tags: [2026](<https://devfeed.tech/tags/2026.md>), [collaboration](<https://devfeed.tech/tags/collaboration.md>), [event](<https://devfeed.tech/tags/event.md>), [events](<https://devfeed.tech/tags/events.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [innovation](<https://devfeed.tech/tags/innovation.md>), [org](<https://devfeed.tech/tags/org.md>), [reproducible-builds](<https://devfeed.tech/tags/reproducible-builds.md>), [summit](<https://devfeed.tech/tags/summit.md>), [tools](<https://devfeed.tech/tags/tools.md>), [users](<https://devfeed.tech/tags/users.md>)

### AI overview

The Reproducible Builds summit will take place in Gothenburg, Sweden, from September 22 to 24, 2026. The event will bring together participants to discuss project status, collaboration, broader adoption, and technical solutions.

### Source excerpt

This event is happening soon -- see below for registration instructions! We are extremely pleased to announce the upcoming Reproducible Builds summit, which will take place from September 22nd--24th 2026 in the city of Gothenburg, Sweden. This year, we are thrilled to host the tenth edition of this exciting event, following the success of previous summits in various iconic locations around the world, including Vienna (2025), Hamburg (2023--2024), Venice (2022), Marrakesh (2019), Paris (2018), Berlin (2017), Berlin (2016) and Athens (2015). If you're excited about joining us this year, please make sure to read the event page which has more details about the event and location. As in previous years, we will be sending invitations to all those who attended our previous summit events or expressed interest to do so. However, even if you do not receive a personal invitation, please do email the organizers and we will find a way to accommodate you. About the event The Reproducible Builds Summit is a unique gathering that brings together attendees from diverse projects, united by a shared vision of advancing the Reproducible Builds effort. During this enriching event, participants will have the opportunity to engage in discussions, establish connections and exchange ideas to drive progress in this vital field. Our aim is to create an inclusive space that fosters collaboration, innovation and problem-solving. Schedule Although the exact content of the meeting will be shaped by the participants, the main goals will include: Update & exchange about the status of reproducible builds in various projects. Improve collaboration both between and inside projects. Expand the scope and reach of reproducible builds to more projects. Work together and hack on solutions. Establish space for more strategic and long-term thinking than is possible in virtual channels. Brainstorm designs on tools enabling users to get the most benefits from reproducible builds. Discuss how reproducible builds w

## AppFunctions, revisited

DevFeed: [AppFunctions, revisited](<https://devfeed.tech/articles/appfunctions-revisited-26158.md>)

Original publisher: [Read original article](<https://dev.to/tkuenneth/appfunctions-revisited-4n90>)

Author: Thomas Künneth

Published: 2026-07-25T11:36:27Z

Content type: tutorial

Language: en

Sources: [Thomas Künneth](<https://devfeed.tech/sources/thomas-kunneth.md>)

Topics: [Jetpack](<https://devfeed.tech/topics/jetpack.md>), [Android](<https://devfeed.tech/topics/android.md>), [Library](<https://devfeed.tech/topics/library.md>), [implementation](<https://devfeed.tech/topics/implementation.md>), [Maven](<https://devfeed.tech/topics/maven.md>)

Tags: [ai](<https://devfeed.tech/tags/ai.md>), [android](<https://devfeed.tech/tags/android.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [article](<https://devfeed.tech/tags/article.md>), [code](<https://devfeed.tech/tags/code.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [jetpack](<https://devfeed.tech/tags/jetpack.md>), [library](<https://devfeed.tech/tags/library.md>), [maven](<https://devfeed.tech/tags/maven.md>), [programming](<https://devfeed.tech/tags/programming.md>), [software](<https://devfeed.tech/tags/software.md>), [update](<https://devfeed.tech/tags/update.md>)

### AI overview

This tutorial revisits Android Jetpack AppFunctions after alpha10 stopped publishing appfunctions-service. It explains the new service entry-point model, generated subclasses and XML, manual service declaration, the removal of AppFunctionContext, and a correction about using installed-app display names instead of package names.

### Source excerpt

In Agentic interaction using AppFunctions I showed how Be nice publishes createAppPair for agents, using Jetpack appfunctions 1.0.0-alpha08. That setup leaned on a library-merged PlatformAppFunctionService, an AppFunctionContext parameter, and aggregate XML named app_functions.xml / app_functions_v2.xml. When I bumped toward what Android Studio was suggesting as of mid July, Sync failed: Could not find androidx.appfunctions:appfunctions-service:1.0.0-alpha10. On 1 July 2026, alpha10 stopped publishing appfunctions-service (Maven still lists it through alpha09). The Add the AppFunctions API guide now expects you to host an @AppFunctionServiceEntryPoint AppFunctionService. Spoiler: that is the real change. The rest of this post is how that landed in Be nice, plus an important update to the earlier article that is easy to miss if you only chase compile errors. Correction first In the earlier post I wrote that agents would pass package names for app1 and app2. That was wrong for Be nice. The implementation matches display names, case-insensitively, against installed apps. Package names are a convenient engineer habit; they are a poor agent habit when the user said "Clock" and "Contacts". KDoc and app-level metadata have to say what the code accepts -- agents lean on that text harder than on your mental model of the APK. What changed in the model Before alpha10 you annotated a helper class and let the service AAR merge a stock entry point into the manifest. Starting with alpha10: @AppFunction lives in androidx.appfunctions (not androidx.appfunctions.service) It is only legal on methods of an abstract AppFunctionService marked @AppFunctionServiceEntryPoint KSP generates the concrete subclass named in serviceName and the XML named in appFunctionXmlFileName You declare that generated service yourself; nothing merges a stock one anymore There is no AppFunctionContext parameter; the service is a Context Drop appfunctions:aggregateAppFunctions. Grepping for empty app_functions.

## Adaptable apps on ChromeOS: a post-mortem

DevFeed: [Adaptable apps on ChromeOS: a post-mortem](<https://devfeed.tech/articles/adaptable-apps-on-chromeos-a-post-mortem-26155.md>)

Original publisher: [Read original article](<https://dev.to/tkuenneth/adaptable-apps-on-chromeos-a-post-mortem-2gl1>)

Author: Thomas Künneth

Published: 2026-05-23T11:26:02Z

Content type: article

Language: en

Sources: [Thomas Künneth](<https://devfeed.tech/sources/thomas-kunneth.md>)

Topics: [Post Mortem](<https://devfeed.tech/topics/post-mortem.md>), [chromebook](<https://devfeed.tech/topics/chromebook.md>), [Android](<https://devfeed.tech/topics/android.md>), [App](<https://devfeed.tech/topics/app.md>), [Development](<https://devfeed.tech/topics/development.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [app](<https://devfeed.tech/tags/app.md>), [chromeos](<https://devfeed.tech/tags/chromeos.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [dev](<https://devfeed.tech/tags/dev.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [post-mortem](<https://devfeed.tech/tags/post-mortem.md>), [software](<https://devfeed.tech/tags/software.md>), [uidesign](<https://devfeed.tech/tags/uidesign.md>)

### AI overview

A post-mortem of attempts to remove ChromeOS's resize confirmation for the Be nice Android app in ARC windows. The article explains how the warning appears in windowed laptop mode, why manifest changes did not remove it on Play Store builds, and how tablet mode differs.

### Source excerpt

In my previous article Building a custom launcher for ChromeOS I described how Be nice runs on Chromebooks: not as a real default home app, because default home settings (Settings.ACTION_HOME_SETTINGS) usually are not available on ChromeOS, but as a normal Android app in an ARC window. I pretended the app is the launcher in code (detectIsHomeApp() returns true on ChromeOS), worked around split-screen bugs that leave the app a black rectangle, and gave up transparent wallpaper for an opaque scaffold because ARC does not show the ChromeOS desktop behind the window the way a phone shows its wallpaper. What that article obviously could not cover is the fight that came right after. For about a week in May 2026 I tried to get rid of a system confirmation ChromeOS shows when users open the preset-size menu in the ARC window title bar and choose Resizable, at least on Play Store builds. During my experiments, manifest changes often looked fine from Android Studio; however, on Play, the dialog stayed. I tried adding XML, asking AI assistants, including Google's own models, for the magic flag. Here's what I learned along the way. What users see ChromeOS does not present Play Store Android apps the same way in every posture. On a convertible or clamshell Chromebook in laptop use, ARC usually places apps in individual windows (chromeos.dev). The title bar often labels the current layout (Phone, Tablet, or Resizable) and opens a menu to switch presets; choosing Resizable is what triggers the warning below, not dragging the window frame by itself (in fact, resizing the window by dragging one of the window edges does not work until it is allowed through the dialog). In tablet mode the picture is different: apps commonly launch and stay full screen, which matches how ChromeOS has long treated touch-first use on detachables (Chrome Unboxed on immersive mode). The resize presets and the warning below matter most when you are in a windowed, laptop-style layout, not when an app is alre

## Building a custom launcher for ChromeOS

DevFeed: [Building a custom launcher for ChromeOS](<https://devfeed.tech/articles/building-a-custom-launcher-for-chromeos-26160.md>)

Original publisher: [Read original article](<https://dev.to/tkuenneth/building-a-custom-launcher-for-chromeos-4fb7>)

Author: Thomas Künneth

Published: 2026-05-14T11:11:33Z

Content type: article

Language: en

Sources: [Thomas Künneth](<https://devfeed.tech/sources/thomas-kunneth.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [App](<https://devfeed.tech/topics/app.md>), [Google](<https://devfeed.tech/topics/google.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [app](<https://devfeed.tech/tags/app.md>), [apps](<https://devfeed.tech/tags/apps.md>), [black-screen](<https://devfeed.tech/tags/black-screen.md>), [chromeos](<https://devfeed.tech/tags/chromeos.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [desktop](<https://devfeed.tech/tags/desktop.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [google](<https://devfeed.tech/tags/google.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [multitasking](<https://devfeed.tech/tags/multitasking.md>), [programming](<https://devfeed.tech/tags/programming.md>), [software](<https://devfeed.tech/tags/software.md>), [ui](<https://devfeed.tech/tags/ui.md>)

### AI overview

The article describes adapting the Be nice Android launcher to run on ChromeOS. It explains that ChromeOS prevents the app from becoming the system launcher, limiting home-screen, wallpaper, gesture, and task-switching integration. It also reports a black-screen bug when Be nice attempts split-screen multitasking.

### Source excerpt

In this article, I will share some of my experience of enhancing Be nice to be a launcher on ChromeOS. Now, why would I want to do that anyway? I use my ChromeOS detachable more like an Android tablet than a traditional laptop; therefore, I find myself deeply missing the Android goodness that Google's desktop OS tends to strip away. Chief among these missing features is support for app widgets. Be nice has app widget support, so it would be great to run my app on ChromeOS. On a standard Android phone or tablet you can simply swap the home app in settings. fun changeDefaultHomeApp() { val intent = Intent(Settings.ACTION_HOME_SETTINGS).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) } if (context.packageManager.resolveActivity( intent, PackageManager.MATCH_DEFAULT_ONLY ) != null ) { context.startActivity(intent) } } Unfortunately, ChromeOS forces you to use its native environment. Consequently, the launcher will be treated just like any other Android app. What does this imply? While we can easily launch other apps, core launcher features like returning to the home screen via the system gesture or home button, acting as the dedicated home activity that fills the display with the normal Android home wallpaper visible behind transparent UI, and integration with the system-level overview or task switcher are not available. Instead, the launcher stays contained within its own window, meaning a swipe up or a press of the Everything Button will still take you back to the native ChromeOS shelf rather than your custom interface. And there is another nasty issue. Before Be nice became a genuine launcher, its main goal was to run two apps side by side, utilizing the split-screen capabilities that are present in Android since 7.0 (Nougat). On ChromeOS, this behavior is consistently buggy. Specifically, when the launcher attempts to start another activity in the adjacent window for a side-by-side view, the originating app (Be nice itself) fails to redraw correctly and simply becom

## Bubble up - Android 17's new multitasking feature explained

DevFeed: [Bubble up - Android 17's new multitasking feature explained](<https://devfeed.tech/articles/bubble-up-android-17-s-new-multitasking-feature-explained-26159.md>)

Original publisher: [Read original article](<https://dev.to/tkuenneth/bubble-up-android-17s-new-multitasking-feature-explained-l58>)

Author: Thomas Künneth

Published: 2026-05-11T14:55:40Z

Content type: article

Language: en

Sources: [Thomas Künneth](<https://devfeed.tech/sources/thomas-kunneth.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [Large Screen](<https://devfeed.tech/topics/large-screen.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [app](<https://devfeed.tech/tags/app.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [feature](<https://devfeed.tech/tags/feature.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [multitasking](<https://devfeed.tech/tags/multitasking.md>), [software](<https://devfeed.tech/tags/software.md>), [ui](<https://devfeed.tech/tags/ui.md>)

### AI overview

The article explains Android 17's new multitasking feature, which lets users turn almost any app into a floating window from its launcher icon, home screen, app drawer, or taskbar. It places the feature in the context of Android's earlier split-screen, multi-window, desktop mode, and chat bubble developments.

### Source excerpt

Only with the release of 12L, Google became serious about making Android a productivity powerhouse across screen sizes and form factors. While we had tablets much earlier, neither the OS nor Mountain View's flagship apps took advantage. With 12L, we got the persistent taskbar, which made dragging and dropping apps into split-screen mode a natural gesture. Subsequent updates like Android 14 and 15 refined this by adding app pairs and improving how the system handles unoptimized apps in multi-window mode. Android 16 introduced the Desktop Mode that allows for freeform window resizing similar to a traditional PC. And yes, we had seen precursors of this much earlier. Android 7.0 Nougat shipped with a hidden freeform windows developer flag, though it languished for years without proper app support or official ecosystem commitment. While ChromeOS can be considered a productivity hub, too (many devices are either detachables or convertibles, and some come with a stylus in the box), it's not Android. Although it runs Android apps (in a container called ArcVM), and even though the apps are shown in freely movable and resizable windows, apps run on an outdated Android version (depending on the device, Android 11, 13, or 15); what's more, the integration is plagued by a couple of annoying user-facing bugs that make the split-screen feature practically unusable. (Chat) Bubbles With chat bubbles, Google introduced an alternative to notifications, specifically targeting conversations. Introduced with Android 11, these floating windows aimed at making chats more accessible without switching apps by putting them on top of other content. The implementation always felt like an experiment. The Bubbles API is an extension of the ShortcutInfo and Notification APIs. To this day, the feature is tied to the MessagingStyle notification category. Consequently, developers can't just bubble any arbitrary app component, limiting a promising windowing concept to a niche utility for messengers li

## Inclusive Login Starts at the First Step

DevFeed: [Inclusive Login Starts at the First Step](<https://devfeed.tech/articles/inclusive-login-starts-at-the-first-step-9082.md>)

Original publisher: [Read original article](<https://uxmag.com/articles/inclusive-login-starts-at-the-first-step>)

Author: Shannon Joycelyn

Published: 2026-04-16T04:13:02Z

Content type: opinion

Language: en

Sources: [UX Magazine](<https://devfeed.tech/sources/ux-magazine.md>)

Topics: [User experience (UX)](<https://devfeed.tech/topics/ux.md>), [Usability](<https://devfeed.tech/topics/usability.md>), [passwords](<https://devfeed.tech/topics/passwords.md>), [Security](<https://devfeed.tech/topics/security.md>)

Tags: [inclusive](<https://devfeed.tech/tags/inclusive.md>), [password](<https://devfeed.tech/tags/password.md>), [people](<https://devfeed.tech/tags/people.md>), [security](<https://devfeed.tech/tags/security.md>), [usability](<https://devfeed.tech/tags/usability.md>), [ux](<https://devfeed.tech/tags/ux.md>)

### AI overview

This article examines how login design can exclude legitimate users through password mismatches, difficult conditions, connectivity problems, and assumptions about private individual credentials. It argues for a more inclusive, human approach to login, with particular attention to older adults and shared-account practices.

### Source excerpt

How often does a login fail even when someone is trying their best? We have been spending more time thinking about inclusivity in the parts of a product that people touch most often. Login is one of them. It appears constantly, is usually justified under security requirements, and often causes momentum to break before anything The post Inclusive Login Starts at the First Step appeared first on UX Magazine.

## Agentic interaction using AppFunctions

DevFeed: [Agentic interaction using AppFunctions](<https://devfeed.tech/articles/agentic-interaction-using-appfunctions-26156.md>)

Original publisher: [Read original article](<https://dev.to/tkuenneth/agentic-interaction-using-appfunctions-m8k>)

Author: Thomas Künneth

Published: 2026-04-06T06:49:26Z

Content type: article

Language: en

Sources: [Thomas Künneth](<https://devfeed.tech/sources/thomas-kunneth.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [API](<https://devfeed.tech/topics/api.md>), [Google](<https://devfeed.tech/topics/google.md>), [App](<https://devfeed.tech/topics/app.md>)

Tags: [agent](<https://devfeed.tech/tags/agent.md>), [agentic](<https://devfeed.tech/tags/agentic.md>), [ai](<https://devfeed.tech/tags/ai.md>), [android](<https://devfeed.tech/tags/android.md>), [api](<https://devfeed.tech/tags/api.md>), [app](<https://devfeed.tech/tags/app.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [google](<https://devfeed.tech/tags/google.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [programming](<https://devfeed.tech/tags/programming.md>), [software](<https://devfeed.tech/tags/software.md>)

### AI overview

This article explains AppFunctions as an Android API for making app capabilities discoverable and executable by agents. It contrasts the model with earlier approaches including App Actions, Android Slices, Direct Actions API, and Assist API, describing limitations such as rigid intents, UI maintenance, foreground-app requirements, and difficulty turning screen data into reliable actions.

### Source excerpt

Given the rise of agentic interaction on Android, we need a fast, reliable API to make app capabilities discoverable and executable by agents. Through the years, Google has introduced several native frameworks to bridge the gap between the operating system, its system-level assistants, and apps. App Actions is the long-standing predecessor to AppFunctions. It uses shortcuts.xml and built-in intents to map specific user requests directly to app features. Android Slices were an attempt to surface interactive snippets of an app's UI directly within the assistant or search interface; they have been effectively deprecated since 2021. Then there's the Direct Actions API, a framework introduced to allow voice assistants to query a foreground app for its specific capabilities in real-time. Gone too. Finally, the Assist API: the fundamental system-level hook that allows a native agent to read the screen context, providing the situational awareness necessary for agents to act on behalf of the user. In retrospect, the failure of these predecessors likely wasn't due to a lack of vision, but rather a fundamental mismatch between static engineering and the needs of dynamic intelligence. App Actions relied on a rigid library of built-in intents. If an app feature didn't fit into one of Google's binding categories, it effectively didn't exist to the assistant. Android Slices were killed by the UI maintenance trap. By forcing developers to build and maintain restricted, templated versions of their interface that often felt out of place, Google asked for too much effort for too little user engagement. The Direct Actions API failed because of its requirement that an app is actively running on the screen, which prevents the assistant from performing tasks autonomously. And while the Assist API provided the eyes for the system, it lacked the intelligence. It could scrape a messy tree of text and nodes from the screen, but it couldn't reliably parse that data into meaningful actions with

## From Vibe-Coding to Reality: Building MarvinSync

DevFeed: [From Vibe-Coding to Reality: Building MarvinSync](<https://devfeed.tech/articles/from-vibe-coding-to-reality-building-marvinsync-26164.md>)

Original publisher: [Read original article](<https://dev.to/tkuenneth/from-vibe-coding-to-reality-building-marvinsync-171h>)

Author: Thomas Künneth

Published: 2026-04-03T13:17:03Z

Content type: opinion

Language: en

Sources: [Thomas Künneth](<https://devfeed.tech/sources/thomas-kunneth.md>)

Topics: [Vibe coding](<https://devfeed.tech/topics/vibe-coding.md>), [Artificial Intelligence](<https://devfeed.tech/topics/ai.md>), [cursor](<https://devfeed.tech/topics/cursor.md>), [macOS](<https://devfeed.tech/topics/macos.md>), [Swift](<https://devfeed.tech/topics/swift.md>), [SwiftUI](<https://devfeed.tech/topics/swiftui.md>), [Filesystems](<https://devfeed.tech/topics/filesystems.md>), [Kotlin Multiplatform](<https://devfeed.tech/topics/kotlin-multiplatform.md>), [Android](<https://devfeed.tech/topics/android.md>), [Wireless Debugging](<https://devfeed.tech/topics/wireless-debugging.md>)

Tags: [adb](<https://devfeed.tech/tags/adb.md>), [ai](<https://devfeed.tech/tags/ai.md>), [android](<https://devfeed.tech/tags/android.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [cursor](<https://devfeed.tech/tags/cursor.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [files](<https://devfeed.tech/tags/files.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [macos](<https://devfeed.tech/tags/macos.md>), [software](<https://devfeed.tech/tags/software.md>), [swift](<https://devfeed.tech/tags/swift.md>), [swiftui](<https://devfeed.tech/tags/swiftui.md>), [vibe-coding](<https://devfeed.tech/tags/vibe-coding.md>)

### AI overview

A post-mortem on building MarvinSync, a macOS utility that synchronizes local music libraries with Android devices through ADB. The author describes using Cursor for AI-assisted Swift development, choosing SwiftUI for a native Mac experience, and replacing unreliable metadata scanning with a folder-based library structure.

### Source excerpt

If you saw my posts back in February on LinkedIn and Mastodon, you know I've been deep in a Cursor session. I promised to pull back the curtain on how MarvinSync--my new macOS utility for syncing local music to Android--came to life through the lens of AI-assisted development. Before we get to the binaries (which are coming soon, I promise!), I want to share the vibe-coding post-mortem of how the first version actually took shape. If you want to follow along with the code as I describe it, the full project is already live on Codeberg. What is MarvinSync? (And why Vibe-Code it?) MarvinSync is a utility designed for a specific niche: people who still believe in local media ownership. It bridges the gap between a curated macOS music library and an Android device. No streaming, no cloud--just your folders, your metadata, and a clean sync via ADB (Android Debug Bridge). But there's a meta-story here. As an Android GDE, I spend my life deep in Kotlin, Compose, and Kotlin Multiplatform. Naturally, KMP would have been the logical choice for a cross-platform sync tool. However, I wanted to take this opportunity to go fully native on the Mac side using Swift and SwiftUI. I'll be the first to admit: I am no Swift expert. This is where vibe-coding comes in. I used Cursor to bridge the gap between my architectural knowledge and my lack of Swift syntax fluency. I provided the vibe--the logic, the structure, and the constraints--and the AI handled the boilerplate and the nuances of a language I'm still learning. Trusting the folder, not the tag One of the first big hurdles was handling music metadata. Initially, we tried the traditional route of scanning ID3 tags using standard APIs. The result was a mess of duplicates and wrong titles that didn't match how my files were actually organized. The solution was to stop being smart with metadata and start being literal with the file system. We shifted to a strict folder-based hierarchy where the directory structure itself defines the librar

## Jetpack's evolution, ecosystem complexity, and a curated Android development stack

DevFeed: [Jetpack's evolution, ecosystem complexity, and a curated Android development stack](<https://devfeed.tech/articles/refuelling-your-jetpack-26165.md>)

Original publisher: [Read original article](<https://dev.to/tkuenneth/refuelling-your-jetpack-d8i>)

Author: Thomas Künneth

Published: 2026-03-08T11:36:03Z

Content type: tutorial

Language: en

Sources: [Thomas Künneth](<https://devfeed.tech/sources/thomas-kunneth.md>)

Topics: [Jetpack](<https://devfeed.tech/topics/jetpack.md>), [Android](<https://devfeed.tech/topics/android.md>), [android-development](<https://devfeed.tech/topics/android-development.md>), [Library](<https://devfeed.tech/topics/library.md>), [Architecture & Design](<https://devfeed.tech/topics/architecture-design.md>), [migration](<https://devfeed.tech/topics/migration.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-architecture](<https://devfeed.tech/tags/android-architecture.md>), [android-development](<https://devfeed.tech/tags/android-development.md>), [architecture-components](<https://devfeed.tech/tags/architecture-components.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [compatibility](<https://devfeed.tech/tags/compatibility.md>), [dependency](<https://devfeed.tech/tags/dependency.md>), [deprecated](<https://devfeed.tech/tags/deprecated.md>), [development](<https://devfeed.tech/tags/development.md>), [ecosystem](<https://devfeed.tech/tags/ecosystem.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [jetpack](<https://devfeed.tech/tags/jetpack.md>), [jetpackcompose](<https://devfeed.tech/tags/jetpackcompose.md>), [kmp](<https://devfeed.tech/tags/kmp.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [library](<https://devfeed.tech/tags/library.md>), [migration](<https://devfeed.tech/tags/migration.md>), [software](<https://devfeed.tech/tags/software.md>)

### AI overview

This article traces Jetpack's evolution from Android Architecture Components and the Support Library to Jetpack and the androidx namespace. It argues that Jetpack's growth to more than 130 artifacts, along with deprecated libraries and multiple solutions for common tasks, has created an ecosystem that developers need to navigate using a curated recommended stack.

### Source excerpt

If you are an Android developer, you know Jetpack. It changed how we build Android apps. But that was long ago. Today, the ecosystem is shifting again. We aren't just building for one platform anymore. We are building for the world. Let me show you how to take the Jetpack libraries you know and use them to fuel a new generation of applications that run everywhere. From Jetpack to a unified architecture First, let's ground ourselves. What exactly is Jetpack? It's more than just a bag of libraries. It is Google's opinionated answer to Android development. It unbundled features from the OS, so we could update our apps without waiting for Android system updates. It gave us backward compatibility. Most importantly, it gave us guidance. It stopped the wild west of Android development and brought us a standard way to build. Before Jetpack, we lived in an era of fragmentation. New features were tied to the OS. If you wanted the latest UI on an older phone, you were out of luck. Eventually, Google introduced the Support Library to fix this. It sort of worked, but it was a mess. We had v4 support, v7 appcompat, v13... it was dependency hell. We needed a reboot. That reboot came in two steps. In 2017, Google announced Android Architecture Components at I/O--ViewModel, Room, Lifecycle, LiveData--and they went 1.0 stable that November. That was the how to architect piece. Then, at I/O 2018, came Jetpack: the umbrella name and the migration to androidx.*. Eventually, everything moved to the new namespace. Libraries were strictly unbundled--own versions, own cycles, semantic versioning so we could reason about compatibility. So: Architecture Components in 2017, Jetpack and androidx in 2018. Today, we have solved one problem but created another: The Jetpack Jungle. There are now over 130 artifacts in the suite. We have historical baggage. Deprecated libraries still sit next to modern ones--for example lifecycle-extensions, which Google deprecated and replaced with separate lifecycle-ru

## Setting up local Codeberg runners

DevFeed: [Setting up local Codeberg runners](<https://devfeed.tech/articles/setting-up-local-codeberg-runners-26166.md>)

Original publisher: [Read original article](<https://dev.to/tkuenneth/setting-up-local-codeberg-runners-4eif>)

Author: Thomas Künneth

Published: 2026-03-02T18:29:02Z

Content type: tutorial

Language: en

Sources: [Thomas Künneth](<https://devfeed.tech/sources/thomas-kunneth.md>)

Topics: [CI/CD](<https://devfeed.tech/topics/cicd.md>), [Docker Compose](<https://devfeed.tech/topics/docker-compose.md>), [Docker](<https://devfeed.tech/topics/docker.md>), [Gitea](<https://devfeed.tech/topics/gitea.md>), [Command-line interface](<https://devfeed.tech/topics/cli.md>), [configuration](<https://devfeed.tech/topics/configuration.md>), [container](<https://devfeed.tech/topics/container.md>)

Tags: [article](<https://devfeed.tech/tags/article.md>), [ci](<https://devfeed.tech/tags/ci.md>), [ci-cd](<https://devfeed.tech/tags/ci-cd.md>), [cicd](<https://devfeed.tech/tags/cicd.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [configuration](<https://devfeed.tech/tags/configuration.md>), [container](<https://devfeed.tech/tags/container.md>), [development](<https://devfeed.tech/tags/development.md>), [docker](<https://devfeed.tech/tags/docker.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [guide](<https://devfeed.tech/tags/guide.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [opensource](<https://devfeed.tech/tags/opensource.md>), [software](<https://devfeed.tech/tags/software.md>), [terminal](<https://devfeed.tech/tags/terminal.md>), [workflow](<https://devfeed.tech/tags/workflow.md>)

### AI overview

This tutorial explains how to set up a local CI/CD runner for Codeberg. It covers registering the runner, configuring and launching a Docker-based runner with Docker Compose, and choosing between the containerized and direct binary methods, including considerations for Mac computers with Apple Silicon and Android builds.

### Source excerpt

In my previous article, First steps towards Codeberg, we looked at how to get set up and comfortable on the platform. Now that your code has a new home, it's time to level up your workflow with automation. While Codeberg provides shared runners for CI/CD, there are plenty of reasons to run your own, among others, performance specific hardware requirements avoiding queue times In this guide , I'll show you how to use your local machine as a CI/CD runner for Codeberg. This works behind firewalls and home routers without needing to expose your IP address. Sounds cool, right? Depending on your needs, you can choose between two setup methods: the containerized approach using Docker / OrbStack, or running the act_runner binary directly. Since I am on a Mac with Apple Silicon, the choice actually matters quite a bit. Docker on M-series chips runs Linux ARM64 images, and unfortunately, the standard Android build tools don't officially support that environment yet. If you are here for Android builds, you might want to look at the binary method; otherwise, Docker is a safe bet. First, get your registration token. On Codeberg, navigate to Settings > Actions > Runners Click Create new runner Copy the Registration Token Next, prepare the workspace. Docker / OrbStack Open your terminal and create a folder to house the runner's identity and configuration. mkdir codeberg-runner cd codeberg-runner After that, create the configuration by putting a file named docker-compose.yml in that folder: code docker-compose.yml Here's how that file should look like. Replace <TOKEN> and <name-of-your-runner> with your registration token and a name for your runner. <name-of-your-runner> will appear in the Codeberg dashboard. services: runner: image: gitea/act_runner:latest container_name: codeberg_runner restart: always environment: - GITEA_INSTANCE_URL=https://codeberg.org - GITEA_RUNNER_REGISTRATION_TOKEN=<TOKEN> - GITEA_RUNNER_NAME=<name-of-your-runner> - ACT_RUNNER_DEFAULT_IMAGE=gitea/runner-i

## First steps towards Codeberg

DevFeed: [First steps towards Codeberg](<https://devfeed.tech/articles/first-steps-towards-codeberg-26163.md>)

Original publisher: [Read original article](<https://dev.to/tkuenneth/first-steps-towards-codeberg-48hl>)

Author: Thomas Künneth

Published: 2025-12-31T11:43:33Z

Content type: tutorial

Language: en

Sources: [Thomas Künneth](<https://devfeed.tech/sources/thomas-kunneth.md>)

Topics: [Open Source](<https://devfeed.tech/topics/open-source.md>), [hosting](<https://devfeed.tech/topics/hosting.md>), [forgejo](<https://devfeed.tech/topics/forgejo.md>), [Gitea](<https://devfeed.tech/topics/gitea.md>), [GitHub](<https://devfeed.tech/topics/github.md>), [bitbucket](<https://devfeed.tech/topics/bitbucket.md>), [passwords](<https://devfeed.tech/topics/passwords.md>)

Tags: [article](<https://devfeed.tech/tags/article.md>), [bitbucket](<https://devfeed.tech/tags/bitbucket.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [development](<https://devfeed.tech/tags/development.md>), [digitalsovereignty](<https://devfeed.tech/tags/digitalsovereignty.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [forgejo](<https://devfeed.tech/tags/forgejo.md>), [gdpr](<https://devfeed.tech/tags/gdpr.md>), [git](<https://devfeed.tech/tags/git.md>), [github](<https://devfeed.tech/tags/github.md>), [hosting](<https://devfeed.tech/tags/hosting.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [open-source](<https://devfeed.tech/tags/open-source.md>), [opensource](<https://devfeed.tech/tags/opensource.md>), [privacy](<https://devfeed.tech/tags/privacy.md>), [software](<https://devfeed.tech/tags/software.md>)

### AI overview

An introductory tutorial about Codeberg, a community-driven, nonprofit platform for hosting software projects. The author explains its open-source, privacy-focused model and demonstrates registering an account and beginning to migrate a GitHub repository.

### Source excerpt

A lot of Europeans are currently talking about Europe having to become more independent from US-based big tech. Being a European myself, I feel the need for this, too. However, just talking won't make a difference. So, why not make this our New Year's resolution? Here's mine: I love open source. Given GitHub's recent trajectory toward centralisation, I feel there are better-suited homes for my repositories. That's why I will start migrating them to Codeberg. What is Codeberg? Codeberg is a community-driven non-profit platform for hosting software projects. Many consider it the leading independent alternative to commercial services like GitHub and Bitbucket. While it looks and feels very similar to GitHub, its underlying philosophy and legal structure are fundamentally different: unlike GitHub, which is owned by Microsoft, Codeberg is run by a German non-profit organisation called Codeberg e.V.. It is funded by donations rather than venture capital or ads. The platform runs on Forgejo, which is a community-governed fork of Gitea. Therefore, the very software used to run the site is itself open source and transparent. And it is privacy-focused. Since Codeberg is hosted in the European Union (Germany), it adheres to strict GDPR standards. It does not track users for advertising and avoids black box AI features like GitHub Copilot. Does this sound appealing? To me it certainly did. That's why I decided to jump right in. In this introductory article, I'll show you my first baby steps, that is, registering and migrating the first GitHub repository. Signing up Registering is a very quick and pleasant experience. Visit https://codeberg.org, find and click the Register button. Just enter a username, your email address, a password, and the randomly generated number or word. Once you click on Register Account, you should receive an email with the inevitable confirmation link. Click on the link to verify your email address. You will be directed to your personal Codeberg landing

## Enshittification: Why I'm leaving dev.to

DevFeed: [Enshittification: Why I'm leaving dev.to](<https://devfeed.tech/articles/enshittification-why-i-m-leaving-dev-to-30460.md>)

Original publisher: [Read original article](<https://dev.to/autonomousapps/enshittification-why-im-leaving-devto-3npn>)

Author: Tony Robalik

Published: 2025-11-30T20:47:58Z

Content type: opinion

Language: en

Sources: [DEV Community: Tony Robalik](<https://devfeed.tech/sources/dev-community-tony-robalik.md>)

Topics: [Web](<https://devfeed.tech/topics/web.md>), [Development](<https://devfeed.tech/topics/development.md>)

Tags: [ai](<https://devfeed.tech/tags/ai.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [dev](<https://devfeed.tech/tags/dev.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [enshittification](<https://devfeed.tech/tags/enshittification.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [software](<https://devfeed.tech/tags/software.md>), [web](<https://devfeed.tech/tags/web.md>)

### AI overview

The author announces that they are leaving dev.to after years of publishing there, citing accumulated site clutter, a soft login wall, dark-pattern popups, and intrusive advertising that obscures the actual article content.

### Source excerpt

With thanks to The Oatmeal for the cover art. See also: enshittification. Please consider reading this post on autonomousapps.com instead. This will be my last post on the site dev.to. I've been posting my blog to that site since April 2018. My very first post was written when I was the Android team lead at Chess.com, titled Rewriting Chess.com's Android app. Over the years, I've been more or less active, and have published 42 posts in all (counting this one).1 I've had concerns about the long-term viability of my presence on that site for a few years, as I've observed layers and layers of cruft accumulate around my actual content. I always had higher priorities though, and justified the cruft by recognizing that the site is providing a free service, and it frankly makes posting a tech blog to the internet fairly easy. The last straw came when, after my most recent post, two separate people contacted me about their experience trying to read it (one of them twice). First I was told that there's a kind of soft login wall when visiting the post. I wasn't aware of this because, as a writer on the site, I'm always logged in. The wall opens when interacting with one of those annoying popups so common on the Web these days: Note there's only one option. Clicking it leads to this: Which fortunately can be dismissed. This is a dark pattern. Then later, someone sent me a screenshot of what it looks like after the login cruft has been brushed away: I've helpfully highlighted the portions of this screencap that are actual content. 21% of the screen real estate! And more than half the remaining is an ad for some bullshit "AI" product. Let me state this very clearly: fuck "AI." It's pure marking speak for a set of technologies founded upon harm, whose primary use-cases are harm. I want nothing to do with it. An auspicious number. ↩

## Java Dependency and Classpath Problems in Gradle and Maven Builds

DevFeed: [Java Dependency and Classpath Problems in Gradle and Maven Builds](<https://devfeed.tech/articles/is-the-java-ecosystem-cursed-a-dependency-analysis-perspective-30463.md>)

Original publisher: [Read original article](<https://dev.to/autonomousapps/is-the-java-ecosystem-cursed-a-dependency-analysis-perspective-53ef>)

Author: Tony Robalik

Published: 2025-11-24T20:15:12Z

Content type: opinion

Language: en

Sources: [DEV Community: Tony Robalik](<https://devfeed.tech/sources/dev-community-tony-robalik.md>)

Topics: [Java](<https://devfeed.tech/topics/java.md>), [Gradle](<https://devfeed.tech/topics/gradle.md>), [Maven](<https://devfeed.tech/topics/maven.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Back end](<https://devfeed.tech/topics/backend.md>)

Tags: [analysis](<https://devfeed.tech/tags/analysis.md>), [build-tool](<https://devfeed.tech/tags/build-tool.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [compilers](<https://devfeed.tech/tags/compilers.md>), [dependencies](<https://devfeed.tech/tags/dependencies.md>), [dependency](<https://devfeed.tech/tags/dependency.md>), [development](<https://devfeed.tech/tags/development.md>), [ecosystem](<https://devfeed.tech/tags/ecosystem.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [gradle](<https://devfeed.tech/tags/gradle.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [java](<https://devfeed.tech/tags/java.md>), [jvm](<https://devfeed.tech/tags/jvm.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [maven](<https://devfeed.tech/tags/maven.md>), [software](<https://devfeed.tech/tags/software.md>), [software-supply-chain-attack](<https://devfeed.tech/tags/software-supply-chain-attack.md>)

### AI overview

This opinion article examines dependency and classpath problems in the Java ecosystem, including misleading metadata, fat JARs, split packages, reflection, protobuf usage, and compiler differences. It explains how classloader behavior can create conflicts and notes that classpath properties can also enable software supply-chain attacks.

### Source excerpt

I am the author of the moderately popular (⭐ 2k) Dependency Analysis Gradle Plugin, a static analysis tool that helps Gradle build authors maintain a healthy dependency graph. I also maintain some of the largest Gradle repos on the planet: a Kotlin backend repo with over 2500 subprojects, and an Android repo with more than 7200 subprojects (both proprietary). I have... seen some shit. Note: I refer to both the cases above as being part of the "Java ecosystem," though both use Kotlin as the preferred language, and one runs on the JVM while the other runs on ART (the Android runtime) on mobile devices. I come to you with a simple proposition: I believe the Java ecosystem is cursed. Hear me out. We are cursed with... Lying metadata, overuse of "fat" jars with underuse of package relocation, split packages, undocumented usage of reflection to access upstream dependencies, usage of terms like "upstream" that have different meanings in different contexts, misuse of protobuffers, different compilers with different notions of their obligations vis-a-vis the Java class file format... Lying metadata This was already covered in-depth in This is why we can't have nice things: When POM files lie, but the summary is: sometimes dependencies have hand-written metadata, which is certainly A Choice given that build tools exist. I suppose it's harder to teach a build tool to lie. It's just a list, man Despite the bewildering complexity of dependency resolution engines in tools like Gradle and Maven, at the end of the day a classpath is just a list of class files (and jars that package class files). When your running program "sees" a class or interface for the first time, it has to load it. It does this with a ClassLoader. The classloader searches the classpath (just a list of class files!)1 and picks the first class file that matches the class it just encountered. Importantly, your classpath may have more than one class file for that class. Even well-behaved builds may have this problem, fo

## Undisclosed bundled dependencies in Kotlin compiler POM metadata

DevFeed: [Undisclosed bundled dependencies in Kotlin compiler POM metadata](<https://devfeed.tech/articles/this-is-why-we-can-t-have-nice-things-when-pom-files-lie-30466.md>)

Original publisher: [Read original article](<https://dev.to/autonomousapps/this-is-why-we-cant-have-nice-things-when-pom-files-lie-3lm5>)

Author: Tony Robalik

Published: 2025-02-07T23:54:47Z

Content type: opinion

Language: en

Sources: [DEV Community: Tony Robalik](<https://devfeed.tech/sources/dev-community-tony-robalik.md>)

Topics: [Dependency management](<https://devfeed.tech/topics/dependency-management.md>), [Java](<https://devfeed.tech/topics/java.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Gradle](<https://devfeed.tech/topics/gradle.md>)

Tags: [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [dependency-management](<https://devfeed.tech/tags/dependency-management.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [gradle](<https://devfeed.tech/tags/gradle.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [java](<https://devfeed.tech/tags/java.md>), [jvm](<https://devfeed.tech/tags/jvm.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [software](<https://devfeed.tech/tags/software.md>)

### AI overview

The author investigates a JVM ClassCastException and traces it to the Kotlin compiler JAR loaded by Gradle. They argue that bundled, unrelocated Guava classes and POM metadata that does not disclose the fat JAR create dependency-management problems.

### Source excerpt

Photo by Marco Bicca on Unsplash. I really hope there's a light at the end of this sewer. Sorry, my country is dissolving into a Nazi sewer of world-historical proportions and so I'm dealing with my otherwise fruitless rage by yelling about JVM things. The fact that Java classes exist in a global namespace is not well-appreciated, even by vendors of major parts of the ecosystem (apparently). Caused by: java.lang.ClassCastException: class com.google.common.graph.ImmutableGraph cannot be cast to class com.google.common.graph.SuccessorsFunction (com.google.common.graph.ImmutableGraph and com.google.common.graph.SuccessorsFunction are in unnamed module of loader org.gradle.internal.classloader.VisitableURLClassLoader$InstrumentingVisitableURLClassLoader @4617120) A confusing error at the best of times, but to a build engineer (i.e. me) trying to help out during a SEV, a despair-inducing example of how Dependency Management on the JVM is Completely Broken, What Are We Even Doing Here. A ClassCastException always means Someone Somewhere Hates You, or at least values their own KPIs more than not polluting the entire goddamn ecosystem. Let's debug! My first step is to navigate to the Graph class and check its hierarchy. I can confirm that, yes, in Guava 33.3.1-jre at least, that class does indeed implement the SuccessorsFunction interface. It should not be throwing a ClassCastException! Next step. In Intellij (the vendor which is ironically the source of this amongst most of the rest of my woes), I set a breakpoint at the exception and evaluate the following expression.1 // `this` is an instance of the `com.google.common.graph.Graph` class this.javaClass.superclass.superclass.superclass.interfaces.first().protectionDomain.codeSource.location That expression resolves to this: file:/Users/<<ME!>>/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-compiler/2.0.21/88f09afc2536e38d528e78eb8349504de10ac436/kotlin-compiler-2.0.21.jar What the fuck! That is not the righ

## Why Engineers Should Replace "Easy" and "Hard" with More Specific Language

DevFeed: [Why Engineers Should Replace "Easy" and "Hard" with More Specific Language](<https://devfeed.tech/articles/hardly-easy-27342.md>)

Original publisher: [Read original article](<https://blog.mmckenna.me/hardly-easy>)

Author: Matt McKenna

Published: 2025-01-29T12:00:32Z

Content type: opinion

Language: en

Sources: [Matt McKenna](<https://devfeed.tech/sources/matt-mckenna.md>)

Topics: [context](<https://devfeed.tech/topics/context.md>), [bug](<https://devfeed.tech/topics/bug.md>)

Tags: [bug](<https://devfeed.tech/tags/bug.md>), [context](<https://devfeed.tech/tags/context.md>), [feelings](<https://devfeed.tech/tags/feelings.md>), [general-advice](<https://devfeed.tech/tags/general-advice.md>), [general-programming](<https://devfeed.tech/tags/general-programming.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [scope](<https://devfeed.tech/tags/scope.md>), [software-engineering](<https://devfeed.tech/tags/software-engineering.md>), [team](<https://devfeed.tech/tags/team.md>)

### AI overview

The article argues that engineers should avoid describing tasks as merely "easy" or "hard." More specific terms such as "small in scope," "straightforward," or "demanding" provide useful context and can help teams communicate more inclusively.

### Source excerpt

Words like "easy" and "hard" can be surprisingly exclusive. Telling someone a task is easy can make them feel ashamed or inadequate if they struggle, while simply labeling something hard fails to provide the context engineers need to understand the t...

## Adding task extensions and typesafe accessors in Gradle Kotlin DSL

DevFeed: [Adding task extensions and typesafe accessors in Gradle Kotlin DSL](<https://devfeed.tech/articles/gradle-extensions-part-2-now-with-shenanigans-30461.md>)

Original publisher: [Read original article](<https://dev.to/autonomousapps/gradle-extensions-part-2-now-with-shenanigans-12m6>)

Author: Tony Robalik

Published: 2024-12-11T23:05:12Z

Content type: tutorial

Language: en

Sources: [DEV Community: Tony Robalik](<https://devfeed.tech/sources/dev-community-tony-robalik.md>)

Topics: [Gradle](<https://devfeed.tech/topics/gradle.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [build](<https://devfeed.tech/tags/build.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [extensions](<https://devfeed.tech/tags/extensions.md>), [gradle](<https://devfeed.tech/tags/gradle.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [java](<https://devfeed.tech/tags/java.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [software](<https://devfeed.tech/tags/software.md>)

### AI overview

This tutorial explains how to add extensions to Gradle tasks and create custom typesafe accessors for use in Kotlin DSL build scripts. It discusses moving shared logic into build-logic, using ProviderFactory, and relying on Gradle's default package imports.

### Source excerpt

Photo by Karsten Würth on Unsplash Welcome to the spiritual successor to Gradle plugins and extensions: A primer for the bemused (one of my most popular posts, such that it competes for space with actual Gradle documentation at the top of a Google search). As part of my long-running quest to Destroy buildSrc With Fire, I have recently had occasion to learn how to add extensions to other kinds of types, such as tasks. We have code like this duplicated across many many repos that are under our care: // buildSrc/src/main/kotlin/magic/Magic.kt package magic object Magic { fun shouldPracticeTheDarkArts(): Boolean { return System.getenv("DO_ANCIENT_MAGIC")?.toBoolean() ?: System.getenv("DO_SLIGHTLY_MORE_MODERN_MAGIC")?.toBoolean() ?: false } } This code is used in build scripts like this: // build.gradle.kts import magic.Magic tasks.withType<Test>().configureEach { if (Magic.shouldPracticeTheDarkArts()) { logger.quiet("👻") } } There are several things about this that I'd like to improve: I don't want this code in buildSrc. I want a version of it in our build-logic that is under test and which is shared widely (instead of duplicated in a dozen different repos). I don't like the import. It is Unclean. (Build scripts should be simple, declarative, easy for tools to parse.) I'm not a big fan of calling System.getenv() in a Gradle context. I prefer to use the ProviderFactory. Extending Test tasks Many Gradle types, including all Tasks (and of course the Project type), are ExtensionAware. This means they all have an ExtensionContainer available on which new extensions can be created and added. // build-logic/src/main/kotlin/magic/TestMagicExtension.kt package magic abstract class TestMagicExtension @Inject constructor( private val providers: ProviderFactory ) { internal companion object { const val NAME = "magic" fun create( testTask: Test, providers: ProviderFactory, ) { testTask.extensions.create( NAME, TestMagicExtension::class.java, providers, ) } } fun shouldPracticeTheDar

## Using DAGP's fixDependencies Task to Repair Gradle Dependencies

DevFeed: [Using DAGP's fixDependencies Task to Repair Gradle Dependencies](<https://devfeed.tech/articles/one-click-dependencies-fix-30465.md>)

Original publisher: [Read original article](<https://dev.to/autonomousapps/one-click-dependencies-fix-191p>)

Author: Tony Robalik

Published: 2024-10-08T18:48:51Z

Content type: article

Language: en

Sources: [DEV Community: Tony Robalik](<https://devfeed.tech/sources/dev-community-tony-robalik.md>)

Topics: [Gradle](<https://devfeed.tech/topics/gradle.md>), [Software Engineering](<https://devfeed.tech/topics/software-engineering.md>), [Tooling](<https://devfeed.tech/topics/tooling.md>)

Tags: [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [debugging](<https://devfeed.tech/tags/debugging.md>), [dependencies](<https://devfeed.tech/tags/dependencies.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [gradle](<https://devfeed.tech/tags/gradle.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [java](<https://devfeed.tech/tags/java.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [software](<https://devfeed.tech/tags/software.md>)

### AI overview

The article examines the Dependency Analysis Gradle Plugin (DAGP), focusing on its fixDependencies task for rewriting Gradle build scripts to address dependency issues. It also discusses risks from analysis bugs and limitations in parsing complex Groovy and Kotlin DSL scripts.

### Source excerpt

Photo by Maxim Hopman on Unsplash If you maintain a JVM1 or Android project, chances are you've heard of the Dependency Analysis Gradle Plugin (DAGP). With over 1800 stars, it's used by some of largest Gradle projects in the world, as well as by Gradle itself. It fills what would otherwise be a substantial hole in the Gradle ecosystem: without it, I know of no other way to eliminate unused dependencies and to correctly declare all your actually-used dependencies. In other words, when you use this plugin, your dependency declarations are exactly what you need to build your project: nothing more, nothing less. That might sound like a small thing, but for industrial-scale projects, a healthy dependency graph is a superpower that prevents bugs, eases debugging (at build and runtime), keeps builds faster, and keeps artifacts smaller. If developer productivity work is the public health of the software engineering world, then a healthy dependency graph is a working sewer system. You don't know how much you rely on it till it stops working and you've got shit everywhere. The problem is that, if your tool only tells you all the problems you have but doesn't also fix them, you might have a massive(ly annoying) problem on your hands. I mentioned this as an important consideration in my recent rant against code style formatters. This is why, since v1.11.0, DAGP has had a fixDependencies task, which takes the problem report and rewrites build scripts in-place. Even before that, in v0.46.0, the plugin had first-class support for registering a "post-processing task" to enable advanced users to consume the "build health" report in any manner of their choosing. Foundry (née The Slack Gradle Plugin), for example, has a feature called the "dependency rake", which predates and inspired fixDependencies. fixDependencies hasn't always worked well, though. For one thing, there might be a bug in the analysis such that, if you "fix" all the issues, your build might break. (DAGP is under very

## Spotlight on CNCF Deaf and Hard-of-hearing Working Group (DHHWG)

DevFeed: [Spotlight on CNCF Deaf and Hard-of-hearing Working Group (DHHWG)](<https://devfeed.tech/articles/spotlight-on-cncf-deaf-and-hard-of-hearing-working-group-dhhwg-17582.md>)

Original publisher: [Read original article](<https://www.kubernetes.dev/blog/2024/09/30/cncf-deaf-and-hard-of-hearing-working-group-spotlight/>)

Author: The Kubernetes Authors

Published: 2024-09-30T00:00:00Z

Content type: article

Language: en

Sources: [Kubernetes Contributors Blog](<https://devfeed.tech/sources/kubernetes-contributors-blog.md>)

Topics: [User interface design](<https://devfeed.tech/topics/ui-design.md>), [Open Source](<https://devfeed.tech/topics/open-source.md>), [Kubernetes](<https://devfeed.tech/topics/kubernetes.md>), [Cloud Native Ecosystem](<https://devfeed.tech/topics/cloud-native-ecosystem.md>), [Maintainers](<https://devfeed.tech/topics/maintainers.md>), [linkerd](<https://devfeed.tech/topics/linkerd.md>)

Tags: [accessibility](<https://devfeed.tech/tags/accessibility.md>), [diversity](<https://devfeed.tech/tags/diversity.md>), [inclusion](<https://devfeed.tech/tags/inclusion.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [kubernetes](<https://devfeed.tech/tags/kubernetes.md>), [linkerd](<https://devfeed.tech/tags/linkerd.md>), [maintainers](<https://devfeed.tech/tags/maintainers.md>), [open-source](<https://devfeed.tech/tags/open-source.md>)

### AI overview

An interview with Catherine Paganini explores the CNCF Deaf and Hard-of-Hearing Working Group, its role in improving inclusion and accessibility, and pathways for people with disabilities to contribute to cloud native open-source projects such as Kubernetes.

### Source excerpt

In recognition of Deaf Awareness Month and the importance of inclusivity in the tech community, we are spotlighting Catherine Paganini , facilitator and one of the founding members of CNCF Deaf and Hard-of-Hearing Working Group (DHHWG). In this interview, Sandeep Kanabar , a deaf member of the DHHWG and part of the Kubernetes SIG ContribEx Communications team , sits down with Catherine to explore the impact of the DHHWG on cloud native projects like Kubernetes. Sandeep's journey is a testament to the power of inclusion. Through his involvement in the DHHWG, he connected with members of the Kubernetes community who encouraged him to join SIG ContribEx - the group responsible for sustaining the Kubernetes contributor experience. In an ecosystem where open-source projects are actively seeking contributors and maintainers, this story highlights how important it is to create pathways for underrepresented groups, including those with disabilities, to contribute their unique perspectives and skills. In this interview, we delve into Catherine's journey, the challenges and triumphs of establishing the DHHWG, and the vision for a more inclusive future in cloud native. We invite Kubernetes contributors, maintainers, and community members to reflect on the significance of empathy, advocacy, and community in fostering a truly inclusive environment for all, and to think about how they can support efforts to increase diversity and accessibility within their own projects. Introduction Sandeep Kanabar (SK): Hello Catherine, could you please introduce yourself, share your professional background, and explain your connection to the Kubernetes ecosystem? Catherine Paganini (CP): I'm the Head of Marketing at Buoyant , the creator of Linkerd , the CNCF-graduated service mesh, and 5th CNCF project. Four years ago, I started contributing to open source. The initial motivation was to make cloud native concepts more accessible to newbies and non-technical people. Without a technical backgrou

## Critique of Enforced Automated Code Formatters

DevFeed: [Critique of Enforced Automated Code Formatters](<https://devfeed.tech/articles/acab-fire-the-code-style-cop-in-your-head-30457.md>)

Original publisher: [Read original article](<https://dev.to/autonomousapps/acab-fire-the-code-style-cop-in-your-head-m8b>)

Author: Tony Robalik

Published: 2024-09-29T18:47:32Z

Content type: opinion

Language: en

Sources: [DEV Community: Tony Robalik](<https://devfeed.tech/sources/dev-community-tony-robalik.md>)

Topics: [formatting](<https://devfeed.tech/topics/formatting.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Gradle](<https://devfeed.tech/topics/gradle.md>), [IntelliJ IDEA](<https://devfeed.tech/topics/intellij-idea.md>)

Tags: [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [formatting](<https://devfeed.tech/tags/formatting.md>), [gradle](<https://devfeed.tech/tags/gradle.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [intellij-idea](<https://devfeed.tech/tags/intellij-idea.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [software](<https://devfeed.tech/tags/software.md>)

### AI overview

An opinion piece arguing against enforced automated code formatters, especially in the author's Kotlin, Gradle, and IntelliJ IDEA workflow. It distinguishes formatting enforcement from linting and questions whether consistent whitespace alone improves readability, maintainability, flow, or error prevention.

### Source excerpt

Photo by Karsten Winegeart on Unsplash Let's get something out of the way right at the start: I hate enforced automated code style formatters. This post started because I had an axe to grind, and I made the ill-advised decision to haul my grindstone out into the public square. Multiple times. Over weeks. Disclaimer! I primarily write Kotlin code that I build with Gradle, in Intellij IDEA (in order of importance). Since many of my complaints are about specific implementation-level issues with code style formatting tools, if you don't also build Kotlin with Gradle, don't worry about it! I'm just an internet crank and you are relieved from the duty of telling me how wrong I am. Second disclaimer! Enforced code style is not the same thing as linting for usage issues. I like linters! Please tell me I forgot to close a stream, or am calling a Java API with ambiguous nullability. Ok, let's gooooo. Arguments in favor of enforcement of consistent code style Consistent code style is better than inconsistent code style Sure. But what do we mean by better? The general claims are: More readable More maintainable Aids with achieving flow Contains fewer errors I think we've already run into an issue, which is we need to clarify what "style" means. Are we just talking about where we break lines and how long those lines are? Or do we mean something deeper? If we are talking about line breaks, I think the argument is pretty weak. Sure, all else being equal, if two pieces of source code follow the same general style, I will have an easier time with pattern-matching and "understanding" them. But what if my pattern-matching misleads me? What if I gloss over the fact that two structurally-identical blocks contain a single semantic difference that entirely changes the behavior? Maybe that single difference is easier to spot if the whitespace is identical, or maybe it's easier to miss because my brain too-readily dismisses the second block as identical to the first. This is actually what c

## Gentler Streak's inclusive, personalized approach to fitness tracking

DevFeed: [Gentler Streak's inclusive, personalized approach to fitness tracking](<https://devfeed.tech/articles/how-gentler-streak-brings-kindness-to-fitness-9107.md>)

Original publisher: [Read original article](<https://www.sketch.com/blog/gentler-streak/>)

Author: Ale Cubero

Published: 2024-09-11T09:23:00Z

Content type: article

Language: en

Sources: [Sketch Blog](<https://devfeed.tech/sources/sketch-blog.md>)

Topics: [personalization](<https://devfeed.tech/topics/personalization.md>), [ui](<https://devfeed.tech/topics/ui.md>), [iOS](<https://devfeed.tech/topics/ios.md>), [User Experience](<https://devfeed.tech/topics/user-experience.md>), [App](<https://devfeed.tech/topics/app.md>)

Tags: [app](<https://devfeed.tech/tags/app.md>), [apple](<https://devfeed.tech/tags/apple.md>), [design](<https://devfeed.tech/tags/design.md>), [fitness](<https://devfeed.tech/tags/fitness.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [ios](<https://devfeed.tech/tags/ios.md>), [made-with-sketch](<https://devfeed.tech/tags/made-with-sketch.md>), [personalization](<https://devfeed.tech/tags/personalization.md>), [ui](<https://devfeed.tech/tags/ui.md>), [ui-ux](<https://devfeed.tech/tags/ui-ux.md>), [user-experience](<https://devfeed.tech/tags/user-experience.md>)

### AI overview

An interview with the Gentler Streak team about designing an inclusive iOS and Apple Watch fitness tracker that provides personalized guidance and encourages sustainable exercise habits. The team also discusses accessibility, empathy, and simplicity in user experience design.

### Source excerpt

We spoke with the team behind Gentler Streak to learn more about their vision for a friendlier, more inclusive fitness tracker, the role of data, and what it takes to maintain simplicity in design.

[Next page](<https://devfeed.tech/tags/inclusive.md?cursor=WyIyMDI0LTA5LTExVDA5OjIzOjAwKzAwOjAwIiwgImI3OWZjZDI4LTE3OTktNGVlYS1iZmZmLWZiYmM1MTE1YTRkMyJd>)