DEV Community

Cover image for SskCore: Turning Production Pain Into an Android Platform
Shubham Nanche
Shubham Nanche

Posted on

SskCore: Turning Production Pain Into an Android Platform

I started with Android apps.

Eventually, I realized I was solving many of the same engineering problems again and again.

Themes. Localization. Notifications. Crash handling. File access. Play integrations. Storage. Build configuration. Release checks. Reusable UI infrastructure.

At first, sharing code between apps feels straightforward.

Then the applications evolve.

One copy gets a bug fix. Another doesn't.

A release requirement changes, so the same logic needs to be updated in several places.

A build-system problem appears in one application, gets fixed locally, and disappears from memory until something similar happens months later.

The code isn't necessarily difficult.

The accumulated engineering knowledge is.

That was the motivation behind SskCore.

SskCore is an internal Android engineering platform I built to turn repeated production lessons into reusable infrastructure, build automation, release safety, and developer tooling across multiple applications.

This article is not a tutorial for building another Android library.

It is a case study in how a collection of recurring application problems gradually turned into a platform.


From shared code to a platform

The first instinct when multiple applications need the same thing is usually to extract it into a library.

That's a good start.

It is not necessarily the end state.

A reusable platform has a different responsibility from a collection of utility functions.

It needs to answer questions like:

  • Which application capabilities belong together?
  • Which dependencies should remain optional?
  • How should consumers integrate the platform?
  • How should changes be released?
  • How can developers iterate quickly without sacrificing release stability?
  • How can recurring mistakes become automated checks?
  • How do you preserve the reasoning behind architectural decisions?

SskCore evolved around those questions.

Instead of copying infrastructure from application to application, shared capabilities became reusable modules with defined boundaries and consumer-facing contracts.

The platform eventually grew to 18 Android modules, supported by shared build logic, custom Gradle automation, release tooling, and extensive documentation.

The important part isn't the number 18.

The important part is why the boundaries exist.


The platform is more than an SDK

At a high level, SskCore can be thought of as several layers.

Foundation

This contains common utilities and lower-level Kotlin support that can be reused without pulling in higher-level application behavior.

Services

These modules provide reusable infrastructure around areas such as:

  • Notifications
  • Play ecosystem integrations
  • Media
  • Storage
  • Search
  • Data utilities
  • Security-aware utilities

UI infrastructure

This layer contains reusable UI and presentation infrastructure, including:

  • Compose utilities
  • XML view helpers
  • Theme and design systems
  • Localization support

Feature components

These are larger reusable capabilities rather than simple helper functions.

Examples include:

  • Text-to-speech orchestration
  • Crash reporting and recovery UX
  • File browsing
  • Task monitoring
  • Other opt-in application capabilities

Build platform

This is where the project starts to look less like a traditional Android SDK.

The build layer provides convention plugins, publishing support, dependency visibility, release checks, and custom quality automation.

The architecture isn't simply "many modules."

The module boundaries exist to control ownership, dependency shape, optional capabilities, and release risk.

That distinction matters.

A large number of modules can just create fragmentation.

Good modularization should instead make the consequences of a dependency more predictable.


The problem with treating every bug as an isolated bug

One of the biggest changes in my thinking came from production debugging.

A traditional debugging loop is:

Something broke → find the cause → fix it → move on.

That works.

But it misses the opportunity to improve the system itself.

With SskCore, I started asking a different set of questions:

Why was this possible?

Why didn't we detect it earlier?

Can the build system identify this class of problem next time?

Can the prevention be reused across every consumer?

Can the lesson be documented so it survives context loss?

That changed the role of the build system.

Instead of being the machinery that turns source code into an APK, it became a place where engineering knowledge could be encoded.


Production bugs should become tools

This became one of the guiding principles behind SskCore:

The most valuable bug fix is often the automated check that prevents the same class of problem from returning.

Some Android failures are difficult to catch through normal development workflows.

They can involve things such as:

  • Resource and packaging interactions
  • Build caching
  • Variant differences
  • Dependency shape
  • Localization gaps
  • Release configuration
  • Cross-module integration

A manual checklist can help.

But a checklist depends on somebody remembering it.

Automation doesn't.

SskCore grew to include 60+ custom build and quality tasks covering areas such as:

  • Release readiness
  • Resource and packaging safety
  • Localization analysis
  • Accessibility checks
  • Dependency visibility
  • Build health
  • Security posture
  • Artifact and bundle workflows
  • Other release and quality checks

These weren't designed as an arbitrary collection of developer tools.

They were largely driven by problems that had already consumed engineering time.

That leads to a principle I now use whenever I encounter a difficult production issue:

Fix the issue. Then encode the lesson.


A build system has to support two different needs

Internal SDKs have an interesting tension.

During active development, engineers want fast feedback.

During release, engineers want stability and reproducibility.

Those goals can pull in different directions.

SskCore was designed around both.

During active work, applications can consume the platform in a way that supports source-level iteration.

For release workflows, the same platform can be consumed through versioned artifacts.

The important thing is not the specific mechanism.

The important thing is the boundary:

developers should be able to move quickly without turning the release dependency graph into something unpredictable.

This became one of the more interesting parts of the platform because it pushed Android build engineering beyond ordinary dependency management.

It required thinking about:

  • Development workflow
  • Artifact versioning
  • Release stability
  • Consumer integration
  • Dependency boundaries
  • Reproducibility

The lesson was broader than Android:

Developer experience and release engineering are not opposing concerns. A good platform has to design for both.


Reusable code is not just extracted code

One of the easiest mistakes in shared infrastructure is assuming that reusable code is simply application code moved into a library.

It isn't.

Application code can make assumptions.

It knows its host.

It knows its screens.

It knows its configuration.

It knows which other components are present.

A reusable platform component doesn't have that luxury.

It needs explicit contracts.

It needs sensible defaults.

It needs predictable integration points.

It needs documentation.

And eventually, it needs a migration story.

That became especially important for larger SskCore capabilities such as text-to-speech orchestration, crash recovery UX, file browsing, localization flows, and task monitoring.

The engineering challenge wasn't simply making them reusable.

It was making them configurable enough for different consumers without forcing every application to understand the platform's internal complexity.

That led to another principle:

Reusable code is not just extracted code. It is code with a contract.


Modularization is about consequences

"Make everything a module" is not an architecture strategy.

The useful question is:

What consequence does this dependency have when an application adopts it?

A monolithic shared module can become convenient in the short term.

It can also accumulate unrelated dependencies and capabilities over time.

SskCore instead separates optional capabilities so that applications can opt into the infrastructure they actually need.

That produces a cleaner dependency graph and makes the relationship between an application and its shared infrastructure easier to reason about.

This is particularly important for Android because the cost of a dependency isn't always limited to another library appearing in a Gradle file.

Dependencies can influence:

  • Build complexity
  • Packaging
  • Application size
  • Permissions
  • Runtime behavior
  • Release risk
  • Maintenance ownership

Good modularization therefore becomes a form of risk management.

Not because every module is inherently safer, but because smaller, intentional boundaries make accidental consequences easier to see.


Documentation became part of the platform

There is another problem that appears once a platform becomes sufficiently complex.

The original author becomes the documentation.

That is not sustainable.

If only one person knows why a particular design exists, the platform carries a hidden operational dependency on that person.

SskCore therefore includes extensive documentation covering areas such as:

  • Architecture
  • Module boundaries
  • Release behavior
  • Recovery
  • Build behavior
  • Troubleshooting
  • Reusable feature integration
  • Engineering decisions

The purpose isn't documentation for documentation's sake.

It's to preserve context.

A future engineer shouldn't have to rediscover the entire reasoning chain behind a design decision simply because the original incident happened months ago.

For me, this changed the definition of developer infrastructure.

Documentation is part of the platform because engineering judgment is part of the platform.


What SskCore changed about how I think about Android

Building SskCore gradually changed my view of Android engineering.

I used to think primarily in terms of application features:

What does this application need to do?

Now I think much more often in terms of platform questions:

What should be reusable?

What should be isolated?

What should the build system know?

What should be automatically verified?

Which assumptions should become contracts?

Which production lessons deserve to become tooling?

That shift is probably the most valuable outcome of the project.

SskCore isn't valuable merely because it contains reusable code.

It is valuable because it captures engineering decisions that otherwise would have been repeatedly rediscovered.


The bigger lesson

The deeper I got into the project, the more I realized that applications are only one layer of software engineering.

Underneath the application are:

  • Build systems
  • SDKs
  • Dependency graphs
  • Release pipelines
  • Quality checks
  • Developer tooling
  • Documentation
  • Operational knowledge

When those layers are designed well, application development becomes easier.

Not because the platform eliminates complexity.

It moves the right complexity into a place where it can be handled once and reused.

That is the real idea behind SskCore.

Turn repeated pain into infrastructure.

Turn infrastructure into contracts.

Turn production lessons into automation.

Turn engineering decisions into documentation.

And then make the next application benefit from everything learned by the previous one.


Where I want to take this thinking

SskCore started as a solution to problems I was repeatedly encountering while building Android applications.

It evolved into something that made me increasingly interested in a different class of engineering work:

  • Android platform engineering
  • Build systems
  • Internal SDKs
  • Developer productivity
  • Release engineering
  • Production debugging
  • Engineering automation

That intersection is what makes the project interesting to me.

The platform beneath an application may not be visible to users.

But it can have an enormous effect on how reliably and efficiently engineers can build what users actually see.

And that is ultimately what SskCore represents:

A collection of hard-earned engineering lessons, turned into reusable infrastructure.

Top comments (0)