[KotlinConf2025] Build your Kotlin and Android apps with Buck2
Sergei Rybalkin, a software engineer from Meta, introduced the audience to Buck2, an open-source build system that is now equipped to support Kotlin and Android applications. In a concise and informative presentation, Rybalkin detailed how Buck2, a successor to the original Buck system, addresses the need for a fast and scalable build solution, particularly for large-scale projects like those at Meta. The talk centered on Buck2’s core principles and its capabilities for accelerating development cycles and ensuring consistent, reliable builds.
The Power of a Scalable Build System
Rybalkin began by outlining the motivation behind Buck2. He explained that as projects grow in size and complexity, traditional build systems often struggle to keep up, leading to slow incremental iterations and hindered developer productivity. Buck2 was designed to overcome these challenges by focusing on key areas such as parallelism and a highly opinionated approach to optimization. The talk revealed that Buck2’s architecture allows it to execute build tasks with remarkable efficiency, a crucial factor for Meta’s own internal development processes. Rybalkin also touched on advanced capabilities like Remote Execution and the Build Tools API, which further enhance the system’s performance and flexibility.
A Blueprint for Optimization
The presentation also shed light on Buck2’s philosophy of “opinionated optimization.” Rybalkin clarified that this means the system takes a firm stance on how things should be done to achieve the best results. For example, if a particular feature or integration does not perform well, the Buck2 team may choose to drop support for it entirely, rather than provide a subpar experience. This selective approach ensures that the build system remains fast and reliable, even as it handles a multitude of dependencies and complex configurations. Rybalkin underscored the fact that the open-source version of Buck2 is almost identical to the internal solution used at Meta, offering the community the same powerful tools and optimizations that drive one of the world’s largest development teams. He concluded by encouraging the audience to try Buck2 and provide feedback, underscoring the collaborative nature of open-source development.
Links:
[NDCOslo2024] Hub-Spoke Virtual Networks in Azure – Bastiaan Wassenaar
In the labyrinthine landscape of Azure’s azure architecture, where connectivity contends with compliance, Bastiaan Wassenaar, a cloud custodian and connectivity connoisseur, clarifies the conundrum of hub-spoke virtual networks. As a Dutch devops dynamo, Bastiaan blueprints the bedrock—endpoints, peering, policies—propelling practitioners past perplexities in private provisioning. His session, a symphony of safeguards and setups, spotlights the saga from service sentinels to spoke sanctuaries, ensuring egress elegance and ingress integrity.
Bastiaan banters on boredom’s behalf: vnet vexations vex veterans, yet victory vaults with vigilance. He heralds history: vnet’s 2014 genesis, endpoints’ evolution, private peers’ precision—pivoting from public perils to partitioned paradises.
Foundations of Fortification: Endpoints and Evolutions
Service endpoints erect ramparts: subnet sentries shielding storage, SQL sans sprawl. Bastiaan bewails bandwidth burdens—10Gbps ceilings—yet blesses them as basics, bridging to private endpoints’ purity: dedicated daisy-chains, DNS delegations demystified.
Hub-spoke’s heartbeat: central hub harboring firewalls, spokes siphoning spokes—peering propagates prefixes, UDRs usher unicast. Bastiaan blueprints: Azure Firewall’s fabric, forced tunneling fortifying flows.
Orchestrating the Orbit: Peering, Policies, and Proxies
Peering’s pact: global gateways, transitive taboos—spokes supplicate hubs for harmony. Bastiaan bemoans BGP’s burdens—bidirectional broadcasts—yet bows to basics: static routes suffice for simplicity.
Policies propel protection: NSGs nestle at NICs, FW’s finesse filters flows. Bastiaan broadcasts best bets: hub’s hegemony, spokes’ seclusion—egress egressing exclusively, ingress inspecting intently.
DNS’s Dominion: Delegations and Dilemmas
DNS dances delicately: private endpoints’ FQDNs, hub’s handlers hijacking queries. Bastiaan bemoans blunders—external IPs eclipsing internals—yet extols overrides: custom configurations, conditional forwarding.
His hack: hosts’ hacks for haste, yet hub’s hegemony harmonizes hordes. Bastiaan broadcasts: reboot realms for resolution—vnet’s vicissitudes vanquished.
Victory’s Vista: Vigilance in Vastness
Bastiaan’s benediction: hub-spoke as haven, harmonizing hazards—history heeded, hurdles hurdled. His hurrah: harness helpers, heed heuristics—Azure’s arsenal awaits.
Links:
[PyDataGlobal2025] Lessons in Decision Making from the Monty Hall Problem
Lecturer
Eyal Kazin is an ex-cosmologist turned data scientist with two decades of experience solving complex quantitative problems. Based in London, he applies statistical and causal inference, machine learning, and optimization methods to produce practical, communicable insights for organizational decision makers. He regularly publishes accessible articles on applied statistics and machine learning on Medium.
Abstract
The Monty Hall problem, popularized by a television game show and later by a magazine column, continues to serve as a rich source of insight into probabilistic reasoning. This article reconstructs the classic three-door formulation, contrasts frequentist and Bayesian analyses, quantifies the informational value of the host’s actions through the notion of surprisal, and extracts a series of decision-making lessons relevant to data science practice. Qualitative and quantitative criteria for recognizing genuine real-world analogues are examined, together with cautionary observations about over-simplification and the limits of analogy.
The Classic Problem and Competing Intuitions
A contestant faces three doors; a prize lies behind one and undesirable objects behind the others. After the contestant selects a door, the host—who knows the prize location—opens a different door that does not conceal the prize and offers the contestant the chance to switch to the remaining closed door. The question is whether switching improves the probability of winning.
A frequentist intuition notes that only two doors remain and therefore assigns equal probability to each, concluding that switching is irrelevant. A Bayesian analysis begins with a uniform prior of one-third on each door. After the contestant’s initial choice, the complementary probability mass of two-thirds resides on the other two doors collectively. When the host reveals one of those doors to be empty, the entire two-thirds mass concentrates on the single remaining unchosen door. Switching therefore doubles the probability of success from one-third to two-thirds.
The same logic becomes intuitively transparent when the number of doors is increased to one hundred or one million. The contestant’s initial selection retains probability (1/n); after the host opens all but one of the remaining doors, the complementary mass ((n-1)/n) resides on the single unopened alternative. The dramatic disparity renders the advantage of switching obvious. Information-theoretic surprisal formalizes the difference: the host’s action conveys progressively more information as (n) grows, widening the gap between the surprisal of the originally chosen door and that of the residual alternative.
Decision-Making Lessons for Data Practice
Several transferable lessons emerge. First, probability assessment is frequently counter-intuitive; Kahneman’s distinction between fast, intuitive System 1 thinking and slower, deliberative System 2 thinking maps directly onto the frequentist versus Bayesian treatments of the problem. Second, ambiguity in problem statements must be resolved explicitly; the host’s policy of never opening the prize door is rarely stated yet is essential to the correct solution. Third, new information should update beliefs rather than be discarded. Fourth, well-designed visualizations—such as exhaustive enumeration of the six equally likely game configurations—can convert an abstract argument into an immediately graspable demonstration. Fifth, multiple solution paths exist; Marilyn vos Savant’s public defense of the Bayesian answer, despite initial resistance from many professional mathematicians, illustrates both the value of alternative representations and the necessity of intellectual humility.
Simulations, while powerful for complex systems, are unnecessary when an exact analytic solution is available; the Monty Hall problem can be solved with pen and paper. Useful analogies should be sought when a problem appears intractable, yet the trade-off between simplification and oversimplification must be kept in view. Occam’s razor, Menken’s warning against excessive simplicity, and Box’s maxim that all models are wrong but some are useful together supply a balanced heuristic.
Real-World Analogues and the Limits of Analogy
Genuine applications must reproduce both the qualitative dependence structure and the quantitative conditional probabilities of the original problem. The host’s choice depends on both the contestant’s selection and the prize location; the two latter variables are independent of each other. Candidate analogies such as short-listing job applicants or adaptive tutoring succeed only when the “host” possesses complete knowledge of the target and the learner has essentially no prior information. Superficial similarities—three cups in a magic trick, for example—satisfy the formal conditions yet remain of limited practical interest. Causal graphs make the required independence and dependence relations explicit and thereby guard against misleading parallels.
Links:
Restoring Bluetooth on Asus N751 After Migrating to Windows 11
Note: The Asus N751JK remains a powerhouse machine. However, Microsoft has arbitrarily denied official Windows 11 migration to this series and other 4th-gen Intel systems. While users can bypass these artificial restrictions, hardware compatibility issues, specifically regarding Bluetooth, are common. This guide addresses how to fix those “unsupported” errors.
One of the most frustrating hurdles after forced migration is the total loss of Bluetooth functionality. In the Device Manager, this typically appears as a generic entry with a yellow exclamation mark and the error: “Windows has stopped this device because it has reported problems (Code 43).”
The Root Cause: Modern Power Management vs. Legacy Hardware
The core of the issue lies in how Windows 11 manages internal USB components. The Bluetooth module in the N751JK is technically a USB-connected device. Windows 11 uses an aggressive “Energy Efficient” protocol known as USB Selective Suspend.
Because the N751’s hardware was designed in 2014, it does not fully support the modern “handshake” required to wake up from these deep sleep states. When Windows tries to save power, the Bluetooth chip “falls asleep” and fails to wake up, leading to the Code 43 crash. To fix this, we must use a stable legacy driver and disable these power-saving constraints.
Step 1: Install the Stable Legacy Driver
First, we must move away from the generic drivers provided by Windows Update. The following Intel driver, though designated for Windows 10, provides the necessary stability for the Windows 11 environment.
| Detail | Specification |
|---|---|
| Device Name | Intel(R) Wireless Bluetooth(R) 4.0 + HS Adapter |
| Driver Version | 17.1.1529.1620 |
| Driver Date | 2015-07-13 |
| Vendor | Intel |
Download Source: Official Driver Repository via Driverscape
Step 2: Disable USB Selective Suspend
Installing the driver is only half the battle. To prevent the Code 43 error from returning, you must disable the global setting that allows Windows to “unplug” your Bluetooth module internally.
- Search for “Edit Power Plan” in the Windows Start menu and open it.
- Click on “Change advanced power settings.”
- Locate and expand “USB settings” > “USB selective suspend setting.”
- Change both “On battery” and “Plugged in” to Disabled.
- Click Apply, then OK, and restart your laptop.
Conclusion
By bypassing the aggressive “Energy Efficient” states that Windows 11 tries to impose on older hardware, we can restore full functionality to the Asus N751JK. This fix proves that with the right configuration, these “unsupported” machines are still highly capable in a modern OS environment.
[PyConUS2025] Lessons from 503 Days of Full-Time Free and Open-Source Software Development
Lecturer
Rodrigo Girão Serrão is a Python educator, author, and independent trainer. He maintains an extensive body of writing on Python, programming, and mathematics at mathspp.com and has published multiple independently produced books on these subjects. Serrão has spoken at major conferences including PyCon US, EuroPython, and various European national PyCons. In late 2024 he established a Guinness World Record for the largest programming lesson. He previously spent 503 consecutive days as a full-time contributor to the Textual terminal-user-interface framework. His professional site is https://mathspp.com and his GitHub handle is rodrigogiraoserrao.
Abstract
Drawing on a continuous year-and-a-half of full-time employment on the Textual open-source project, Rodrigo Girão Serrão reflects on non-technical lessons acquired in that environment. The presentation examines the role of public online activity in obtaining technical work, the management of personal ego within a stronger team, constructive responses to error and code review, the practical demands of user and contributor interaction, and strategies for navigating a large codebase that exceeds individual working memory. The account is explicitly subjective yet offers transferable observations for anyone collaborating on substantial software, whether proprietary or free.
Obtaining Work and Managing Ego in Collaborative Settings
Serrão begins by stressing that every public artifact—blog posts, code repositories, conference talks, social-media interactions—functions as a continuous advertisement of one’s capabilities and temperament. In his own case, sustained technical writing created intermittent contact with the eventual employer; over time that contact matured into an offer of full-time open-source employment. He is careful to acknowledge the element of chance while simultaneously insisting that chance can be cultivated: consistent public output raises the probability that a future opportunity will intersect with an existing relationship. Attendance at events such as PyCon further multiplies those intersections.
Once inside a team that contained stronger Python practitioners than himself, Serrão confronted the necessity of subordinating ego. Previously the sole Python developer in smaller organizations, he had been simultaneously the best and the worst practitioner by definition. The new environment inverted that status. Rather than experience the change as loss, he reframed it as an accelerated learning opportunity. The presence of more experienced colleagues meant that disagreements could be treated as tuition rather than threats. Code reviews, in particular, became occasions to inquire why a particular solution was preferred, thereby converting potential confrontation into knowledge transfer. The discipline required is emotional as much as technical: one must deliberately set aside the impulse to defend one’s first draft and instead treat every requested change as data about better practice.
Honest mistakes are inevitable and, within a healthy team, permissible; repetition of the same mistake is not. Serrão illustrates the point with self-deprecating examples, including a pull-request history that initially appeared to worsen rather than improve and an issue report whose essence reduced to the complaint that “Python ran when I ran Python.” The episode, quickly closed in embarrassment, underscores both the ubiquity of error and the protective value of a non-punitive culture. The operative rule is simple: never make the identical error twice.
Interacting with Users and Navigating Large Codebases
Users are simultaneously the justification for open-source labor and a persistent source of friction. Interaction consumes time and emotional energy, especially when bug reports lack minimal reproducible examples or when pull requests ignore project conventions. Serrão’s central recommendation is the creation of a thorough contributing guide, not because contributors will read it voluntarily, but because the document can be cited in responses. Issue templates that solicit terminal version, operating-system details, and other project-specific context further reduce diagnostic cycles. The first reply to any issue or pull request should be rapid—even if it consists only of an acknowledgment and a pointer to the guide—because prolonged silence communicates indifference and can discourage first-time contributors.
Kindness that borders on the excessive is advised. Textual communication strips away tone; what feels playful to the writer may read as curt or sarcastic to the recipient. Over-compensation with explicit warmth therefore functions as insurance. When a pull request must be declined, Serrão attempts to extract any salvageable fragment, open a new pull request containing that fragment, and credit the original author as co-author. The gesture preserves the contributor’s sense of impact and avoids the appearance of appropriation.
A large codebase cannot be held entirely in working memory. Serrão therefore maintains four persistent heuristics while making changes: (1) prioritize the experience of the end user over the convenience of the implementer; (2) attend to the spirit rather than the letter of an issue description; (3) accept the burden of tedious or difficult work so that downstream developers face fewer obstacles; and (4) evaluate every design decision for the reasonable future possibilities it might foreclose. Before opening a pull request he converts it to draft status and performs a self-review, catching many defects before they reach colleagues. Finally, he insists on running the full test suite; the project’s complexity guarantees that untested changes will break something.
The cumulative effect of these practices is a posture of continuous, ego-light learning. Public writing may open doors; humility and systematic kindness keep them open. A contributing guide and disciplined self-review protect both the project’s quality and the psychological safety of its participants. Although Serrão no longer works full-time on open source, the habits formed during those 503 days continue to shape his work as an educator and independent practitioner.
Links:
Option[Scala] != Optional
Java Optional and Scala Option: A Shared Goal, Divergent Philosophies
The absence of a value is one of the most deceptively complex problems in software engineering. For decades, mainstream programming languages relied on a single mechanism to represent it: null. While convenient, this design choice has proven to be one of the most costly abstractions in computing, as famously described by Tony Hoare as his “billion-dollar mistake”. Both Java and Scala eventually introduced explicit abstractions—Optional in Java and Option in Scala—to address this long-standing issue. Although these constructs appear similar on the surface, their design, intended usage, and expressive power differ in ways that reflect the deeper philosophies of their respective languages.
Understanding these differences requires examining not only their APIs, but also how they are used in real code.
Historical Background and Design Motivation
Scala introduced Option as a core concept from its earliest releases. Rooted in functional programming traditions, Scala treats the presence or absence of a value as a fundamental modeling concern. The language encourages developers to encode uncertainty directly into types and to resolve it through composition rather than defensive checks.
Java’s Optional, introduced much later in Java 8, emerged in a very different context. It was part of a cautious modernization effort that added functional elements without breaking compatibility with an enormous existing ecosystem. As a result, Optional was intentionally constrained and positioned primarily as a safer alternative to returning null from methods.
Modeling Presence and Absence
In Scala, an optional value is represented as either Some(value) or None. This is a closed hierarchy, and the distinction is explicit at all times.
def findUser(id: Int): Option[String] =
if (id == 1) Some("Alice") else None
In Java, the equivalent method returns an Optional created through a factory method.
Optional<String> findUser(int id) {
return id == 1 ? Optional.of("Alice") : Optional.empty();
}
At first glance, these examples appear nearly identical. The difference becomes more pronounced in how these values are consumed and composed.
Consumption and Transformation
Scala’s Option integrates deeply with the language’s expression-oriented style. Transformations are natural and idiomatic, and optional values behave much like collections with zero or one element.
val upperName =
findUser(1)
.map(_.toUpperCase)
.filter(_.startsWith("A"))
In this example, absence propagates automatically. If findUser returns None, the entire expression evaluates to None without any additional checks.
Java’s Optional supports similar operations, but the style is more constrained and often more verbose.
Optional<String> upperName =
findUser(1)
.map(String::toUpperCase)
.filter(name -> name.startsWith("A"));
Although the semantics are similar, Java’s syntax and type system make these chains feel more deliberate and less fluid, reinforcing the idea that Optional is a special-purpose construct rather than a universal modeling tool.
Extracting Values: Intentional Friction vs Idiomatic Resolution
Scala encourages developers to resolve optional values through pattern matching or total functions such as getOrElse.
val name = findUser(2) match {
case Some(value) => value
case None => "Unknown"
}
A concise fallback can also be expressed directly:
val name = findUser(2).getOrElse("Unknown")
In Java, extracting a value is intentionally more guarded. While get() exists, its use is discouraged in favor of safer alternatives.
String name = findUser(2).orElse("Unknown");
The difference is cultural rather than technical. In Scala, resolving an Option is a normal part of control flow. In Java, consuming an Optional is treated as an exceptional act that should be handled carefully and explicitly.
Optional Values in Composition
Scala excels at composing multiple optional computations using flatMap or for-comprehensions.
for {
user <- findUser(1)
email <- findEmail(user)
} yield email
This code expresses dependent computations declaratively. If any step yields None, the entire expression evaluates to None.
In Java, the same logic requires more explicit wiring.
Optional<String> email =
findUser(1).flatMap(user -> findEmail(user));
While functional, the Java version becomes less readable as the number of dependent steps increases.
Usage as Fields and Parameters
Scala allows Option to be used freely as a field or parameter type, which is common and idiomatic.
case class User(name: String, email: Option[String])
Java, by contrast, discourages the use of Optional in fields or parameters, even though it is technically possible.
// Generally discouraged
class User {
Optional<String> email;
}
This contrast highlights Scala’s confidence in Option as a foundational abstraction, while Java treats Optional as a boundary marker in API design.
Philosophical Implications
The contrast between Option and Optional mirrors the broader philosophies of Scala and Java. Scala embraces expressive power and abstraction to manage complexity. Java favors incremental evolution and clarity, even when that limits expressiveness.
Both approaches are valid, and both significantly reduce errors when used appropriately.
Conclusion
Java’s Optional and Scala’s Option address the same fundamental problem, yet they do so in ways that reflect the deeper identity of their ecosystems. Scala’s Option is a first-class participant in program structure, encouraging composition and declarative reasoning. Java’s Optional is a carefully scoped enhancement, designed to improve API safety without redefining the language.
What appears to be a minor syntactic distinction is, in reality, a clear illustration of two distinct approaches to software design on the JVM.
[KotlinConf2024] Compose Multiplatform Evolves on iOS and Beyond
At KotlinConf2024, Sebastian Aigner, a JetBrains developer advocate, unveiled advancements in Compose Multiplatform, now in beta for iOS and alpha for web. Extending beyond business logic, Compose enables shared UI across platforms, integrating native capabilities. Sebastian showcased new common APIs—previews, resources, lifecycle, navigation, and UI testing—alongside iOS-specific enhancements like accessibility and scroll physics. Through live demos, he demonstrated how these features simplify cross-platform development, inviting developers to shape Compose’s future with feedback.
A Year of Progress for Compose Multiplatform
Since its debut at KotlinConf2023, Compose Multiplatform has matured significantly. Sebastian highlighted its role in sharing UI code, complementing Kotlin Multiplatform’s business logic sharing. On Android, it leverages Jetpack Compose; on desktop, it powers JetBrains Toolbox; and on iOS, it reached beta status at KotlinConf2024. The web target hit alpha, broadening its reach. Progress spans accessibility, navigation, text input, and scroll physics, with most features now stable or experimental, ready for developers to adopt and refine through real-world use.
iOS-Specific Enhancements
Compose Multiplatform on iOS now feels native, thanks to revamped scroll physics mirroring iOS’s overscroll and spring effects. Sebastian demonstrated accessibility improvements, with components supporting VoiceOver and gesture navigation out of the box, provided content descriptions are added. Interop with SwiftUI allows popups to span the screen, and window insets APIs handle notches and dynamic islands, ensuring full-screen rendering. These enhancements make iOS apps built with Compose visually and functionally indistinguishable from native counterparts, enhancing user experience.
Common Resources for Seamless UI
The new common resources API simplifies asset management. Sebastian showed how to add drawables and strings in a composeResources directory, accessed via a type-safe res object. In a demo, he added a banner image and a localized conference description, with Fleet auto-generating accessors. Support for multimodule resources and translations (e.g., German dark mode) ensures flexibility. This API, familiar from Android, reduces boilerplate, letting developers focus on crafting polished, platform-agnostic UIs with minimal effort.
Lifecycle and View Models in Common Code
Compose Multiplatform now supports common lifecycle and view model APIs, enabling robust app architecture. Sebastian demonstrated a lifecycle logger tracking states like onCreate and onPause, with collectAsStateWithLifecycle ensuring efficient flow collection. In a view model demo, he outsourced mood-tracking logic, using a factory function to instantiate it. Integration with Koin for dependency injection and lifecycle-aware state collection streamlines development, making MVVM patterns viable across platforms without platform-specific workarounds.
Navigation for Cross-Platform Apps
Navigation, a cornerstone of multiplatform apps, is now available via a Jetpack Navigation-inspired API. Sebastian built a demo app with a fruit list and detail pages, using a NavHost and NavController for stack-based navigation. Features like window insets padding, animated transitions, and rememberSaveable for state persistence ensure a native feel. Type-safe routing with Kotlinx.serialization is in development, reducing errors. This API, while optional, simplifies porting Android navigation logic to iOS and beyond, enhancing developer productivity.
UI Testing and Community Feedback
A new common UI testing API allows writing tests once for all platforms. Sebastian showed a test verifying a composable’s text content, executed across targets. This reduces testing overhead, ensuring consistent behavior. He urged developers to try these features, citing the Compose Multiplatform portal (jb.compose) for documentation. Feedback via the Kotlin Slack and issue tracker is vital, as community input drives stabilization. With support for features like strong skipping mode and shared element transitions, Compose continues to evolve dynamically.
Links:
[KotlinConf2024] Compose Multiplatform Evolves on iOS and Beyond
At KotlinConf2024, Sebastian Aigner, a JetBrains developer advocate, unveiled advancements in Compose Multiplatform, now in beta for iOS and alpha for web. Extending beyond business logic, Compose enables shared UI across platforms, integrating native capabilities. Sebastian showcased new common APIs—previews, resources, lifecycle, navigation, and UI testing—alongside iOS-specific enhancements like accessibility and scroll physics. Through live demos, he demonstrated how these features simplify cross-platform development, inviting developers to shape Compose’s future with feedback.
A Year of Progress for Compose Multiplatform
Since its debut at KotlinConf2023, Compose Multiplatform has matured significantly. Sebastian highlighted its role in sharing UI code, complementing Kotlin Multiplatform’s business logic sharing. On Android, it leverages Jetpack Compose; on desktop, it powers JetBrains Toolbox; and on iOS, it reached beta status at KotlinConf2024. The web target hit alpha, broadening its reach. Progress spans accessibility, navigation, text input, and scroll physics, with most features now stable or experimental, ready for developers to adopt and refine through real-world use.
iOS-Specific Enhancements
Compose Multiplatform on iOS now feels native, thanks to revamped scroll physics mirroring iOS’s overscroll and spring effects. Sebastian demonstrated accessibility improvements, with components supporting VoiceOver and gesture navigation out of the box, provided content descriptions are added. Interop with SwiftUI allows popups to span the screen, and window insets APIs handle notches and dynamic islands, ensuring full-screen rendering. These enhancements make iOS apps built with Compose visually and functionally indistinguishable from native counterparts, enhancing user experience.
Common Resources for Seamless UI
The new common resources API simplifies asset management. Sebastian showed how to add drawables and strings in a composeResources directory, accessed via a type-safe res object. In a demo, he added a banner image and a localized conference description, with Fleet auto-generating accessors. Support for multimodule resources and translations (e.g., German dark mode) ensures flexibility. This API, familiar from Android, reduces boilerplate, letting developers focus on crafting polished, platform-agnostic UIs with minimal effort.
Lifecycle and View Models in Common Code
Compose Multiplatform now supports common lifecycle and view model APIs, enabling robust app architecture. Sebastian demonstrated a lifecycle logger tracking states like onCreate and onPause, with collectAsStateWithLifecycle ensuring efficient flow collection. In a view model demo, he outsourced mood-tracking logic, using a factory function to instantiate it. Integration with Koin for dependency injection and lifecycle-aware state collection streamlines development, making MVVM patterns viable across platforms without platform-specific workarounds.
Navigation for Cross-Platform Apps
Navigation, a cornerstone of multiplatform apps, is now available via a Jetpack Navigation-inspired API. Sebastian built a demo app with a fruit list and detail pages, using a NavHost and NavController for stack-based navigation. Features like window insets padding, animated transitions, and rememberSaveable for state persistence ensure a native feel. Type-safe routing with Kotlinx.serialization is in development, reducing errors. This API, while optional, simplifies porting Android navigation logic to iOS and beyond, enhancing developer productivity.
UI Testing and Community Feedback
A new common UI testing API allows writing tests once for all platforms. Sebastian showed a test verifying a composable’s text content, executed across targets. This reduces testing overhead, ensuring consistent behavior. He urged developers to try these features, citing the Compose Multiplatform portal (jb.compose) for documentation. Feedback via the Kotlin Slack and issue tracker is vital, as community input drives stabilization. With support for features like strong skipping mode and shared element transitions, Compose continues to evolve dynamically.
Links:
[DevoxxGR2025] Optimized Kubernetes Scaling with Karpenter
Alex König, an AWS expert, delivered a 39-minute talk at Devoxx Greece 2025, exploring how Karpenter enhances Kubernetes cluster autoscaling for speed, cost-efficiency, and availability.
Karpenter’s Dynamic Autoscaling
König introduced Karpenter as an open-source, Kubernetes-native autoscaling solution, contrasting it with the traditional Cluster Autoscaler. Unlike the latter, which relies on uniform node groups (e.g., nodes with four CPUs and 16GB RAM), Karpenter uses the EC2 Fleet API to dynamically provision nodes tailored to workload needs. For instance, if a pod requires one CPU, Karpenter allocates a node with minimal excess capacity, avoiding resource waste. This right-sizing, combined with groupless scaling, enables faster and more cost-effective scaling, especially in dynamic environments.
Ensuring Availability with Constraints
König addressed availability challenges reported by users, emphasizing Kubernetes-native scheduling constraints to mitigate disruptions. Topology spread constraints distribute pods across availability zones, reducing the risk of downtime if a node fails. Pod disruption budgets, affinity/anti-affinity rules, and priority classes further ensure critical workloads are scheduled appropriately. For stateful workloads using EBS, König recommended setting the volume binding mode to “wait for first consumer” to avoid pod-volume mismatches across zones, preventing crashes and ensuring reliability.
Integrating with KEDA for Application Scaling
For advanced scaling, König highlighted combining Karpenter with KEDA for event-driven, application-specific scaling. KEDA scales pods based on metrics like Kafka topic sizes or SQS queues, beyond CPU/memory. Karpenter then provisions nodes for pending pods, enabling seamless scaling for workloads like flash sales. König outlined a four-step migration from Cluster Autoscaler to Karpenter, emphasizing its simplicity and open-source documentation.
Links
[GoogleIO2025] What’s new in Jetpack Compose
Keynote Speaker
Jolanda Verhoef serves as a Developer Relations Engineer at Google, specializing in Android development with a focus on Jetpack Compose and user interface tooling. Based in Utrecht, she advocates for modern UI practices, drawing from her education at the University of Utrecht to educate developers on building efficient, adaptive applications.
Abstract
This scholarly exploration delves into the recent enhancements within Jetpack Compose, Google’s declarative UI framework for Android, emphasizing features that bolster developer efficiency, runtime optimization, and library extensibility. It scrutinizes novel APIs for autofill, text scaling, and visibility monitoring, alongside performance upgrades and stability refinements, elucidating their design rationales, integration techniques, and potential influences on application architecture. Through code illustrations and case analyses, the narrative reveals how these advancements facilitate the creation of resilient, cross-platform interfaces, fostering accelerated development cycles in contemporary mobile ecosystems.
Innovations in Features and Usability
Jolanda Verhoef opens by reflecting on Jetpack Compose’s trajectory since its inception as an experimental toolkit in 2019, evolving into the premier recommendation for Android UI construction. She asserts that its adoption, now encompassing 60% of top-tier applications, stems from its capacity to expedite development while yielding aesthetically pleasing, responsive interfaces. This growth contextualizes within Android’s maturation, where Compose addresses the demand for tools that prioritize user-centric innovations over legacy constraints.
A cornerstone update is autofill integration, enabling seamless population of form fields with pre-stored user data. Verhoef explains that implementation necessitated a comprehensive overhaul of Compose’s semantics infrastructure to align with system-level autofill services. In practice, developers apply a semantics modifier to text fields, specifying roles such as username or password via a content type property. This methodology not only enhances accessibility but also streamlines user interactions, reducing friction in authentication flows.
Code sample for basic autofill:
TextField(
value = username,
onValueChange = { username = it },
modifier = Modifier.semantics {
contentType = AutofillType.Username
}
)
For alpha releases, a dedicated contentType modifier simplifies this to a single line, illustrating Compose’s commitment to concise, expressive APIs. Implications include improved retention through effortless onboarding, though developers must consider privacy implications in data handling.
Autosizing text emerges as another usability boon, automatically adjusting font dimensions to fit containers. By appending an autoSize parameter to Text composables, with configurable minima, maxima, and step granularities, layouts dynamically adapt without manual interventions. This innovation mitigates overflow issues in variable screen environments, such as foldables, promoting inclusivity across device spectra.
The animateBounds modifier facilitates concurrent animation of size and position within lookahead scopes, optimizing for fluid transitions in adaptive UIs. Verhoef highlights its utility in scenarios like content resizing during orientation shifts, where traditional animations might falter.
Visibility tracking receives low-level support via onLayoutRectChanged, a performant callback for monitoring composable positions relative to roots, windows, or screens. Superior to onGloballyPositioned due to inherent throttling and debouncing, it suits high-frequency tasks like scroll-based analytics. Alpha extensions, including onVisibilityChanged for viewport entry/exit detection and onVisibilityFractionChanged for partial exposure ratios, elevate this to higher abstractions. These enable sophisticated features like auto-pausing videos or lazy loading, with implications for battery efficiency and data conservation in media-heavy apps.
Methodologically, these features leverage Compose’s recomposition model, where UI reacts to state changes without imperative redraws. Contextually, they respond to developer feedback for streamlined tooling, implying broader adoption by reducing barriers to advanced functionalities.
Enhancements in Performance, Stability, and Ecosystem Libraries
Verhoef transitions to performance optimizations, underscoring Compose’s maturation through rigorous benchmarking. Compiler advancements, including stable skipping for non-recomposable lambdas, halve recomposition times in benchmarks, enhancing responsiveness in complex hierarchies. UI toolkit refinements, such as deferred subcomposition and optimized modifier chains, yield 20-30% frame rate gains in scrolling lists.
Stability efforts involve a 32% reduction in experimental APIs via deprecations and stabilizations, with core modules like Foundation and UI achieving 66% cuts. This bolsters confidence in production deployments, mitigating migration risks.
Ecosystem expansion integrates Compose with broader Jetpack suites. Navigation 3, an alpha artifact, reimagines routing with Compose idioms, offering layered architectures for adaptive, customizable flows across form factors, including XR. It supports transitions, predictive back navigation, and Material Design, with full backstack control for bespoke needs.
Media and camera libraries receive Compose-native building blocks via Media3 and CameraX, eschewing view wrappers for granular control. In Androidify, a tutorial video employs PlayerSurface for rendering and custom play-pause states, demonstrating modular composition.
Code sample for media playback:
VideoPlayer(player = player) {
PlayerSurface(player = player)
MyPlayPauseButton(player = player)
}
These libraries empower tailored experiences, implying versatile media integrations without vendor lock-in.
Overall, these enhancements contextualize within Android’s push for unified, efficient development. Implications span accelerated prototyping, reduced maintenance, and enriched user engagements, positioning Compose as indispensable for future-proof Android endeavors.