DEV Community

boryanz
boryanz

Posted on

Why every Android dev needs a template repository? 💻

Why Every Android Developer Should Have a Jetpack Compose Boilerplate Template Repository

Starting new projects from scratch is tedious. And when you're working with Jetpack Compose, setting up the same dependencies, navigation, themes, and basic structure every time makes you bang your head against the wall.

That's why I created AndroidBlitz boilerplate.

The Problem with Starting from Scratch

...you need navigation, state management, dependency injection, network calls, proper theming, and testing setup. Setting this up every time wastes hours, sometimes days! It drains my whole motivation to continue with the app develpment.

I tracked once, it takes me about 3-4 hours to set up a proper project structure with all the essentials. That's half a working day gone before writing any actual feature code.

What Should Your Boilerplate Include?

Based on my experience, here's what your template should have:

Core Dependencies

Your build.gradle.kts should include the essentials:

dependencies {
    implementation(libs.androidx.core.ktx)
    implementation(libs.androidx.lifecycle.runtime.ktx)
    implementation(libs.androidx.activity.compose)
    implementation(platform(libs.androidx.compose.bom))
    implementation(libs.androidx.compose.ui)
    implementation(libs.androidx.compose.ui.tooling.preview)
    implementation(libs.androidx.compose.material3)
    implementation(libs.androidx.navigation.compose)
    implementation(libs.hilt.android)
    implementation(libs.hilt.navigation.compose)
    kapt(libs.hilt.compiler)
    implementation(libs.retrofit)
    implementation(libs.retrofit.converter.gson)
    implementation(libs.okhttp.logging.interceptor)
    testImplementation(libs.junit)
    androidTestImplementation(libs.androidx.junit)
    androidTestImplementation(libs.androidx.espresso.core)
}
Enter fullscreen mode Exit fullscreen mode

Navigation Setup

Set up navigation with proper route handling:

@Composable
fun AppNavigation() {
    val navController = rememberNavController()

    NavHost(
        navController = navController,
        startDestination = "home"
    ) {
        composable("home") {
            HomeScreen(
                onNavigateToDetails = { id ->
                    navController.navigate("details/$id")
                }
            )
        }
        composable(
            "details/{id}",
            arguments = listOf(navArgument("id") { type = NavType.StringType })
        ) { backStackEntry ->
            val id = backStackEntry.arguments?.getString("id") ?: ""
            DetailsScreen(
                id = id,
                onBack = { navController.popBackStack() }
            )
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Dependency Injection Structure

Hilt modules for common dependencies:

@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {

    @Provides
    @Singleton
    fun provideOkHttpClient(): OkHttpClient {
        return OkHttpClient.Builder()
            .addInterceptor(HttpLoggingInterceptor().apply {
                level = if (BuildConfig.DEBUG) {
                    HttpLoggingInterceptor.Level.BODY
                } else {
                    HttpLoggingInterceptor.Level.NONE
                }
            })
            .build()
    }

    @Provides
    @Singleton
    fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
        return Retrofit.Builder()
            .baseUrl("https://api.example.com/")
            .client(okHttpClient)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }
}
Enter fullscreen mode Exit fullscreen mode

Theme and Styling

A proper Material 3 theme setup:

@Composable
fun AppTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit
) {
    val colorScheme = when {
        darkTheme -> DarkColorScheme
        else -> LightColorScheme
    }

    MaterialTheme(
        colorScheme = colorScheme,
        typography = Typography,
        content = content
    )
}
Enter fullscreen mode Exit fullscreen mode

Testing Setup

Include basic testing utilities:

@RunWith(AndroidJUnit4::class)
@HiltAndroidTest
class ExampleInstrumentedTest {

    @get:Rule
    val hiltRule = HiltAndroidRule(this)

    @get:Rule
    val composeTestRule = createAndroidComposeRule<MainActivity>()

    @Test
    fun testExample() {
        composeTestRule.setContent {
            AppTheme {
                HomeScreen()
            }
        }

        composeTestRule.onNodeWithText("Hello").assertIsDisplayed()
    }
}
Enter fullscreen mode Exit fullscreen mode

Why This Saves Time

With a proper boilerplate, starting a new project takes 10 minutes instead of hours. You clone the template, rename the package, update the app name, and you're ready to build features.

I've used my template for 5 different projects now. Each time, I just focus on the business logic instead of setting up the same infrastructure over and over.

The reasons I created AndroidBlitz, and why you should have it

Core Value Proposition

AndroidBlitz accelerates Android development by providing a production-ready foundation that eliminates the need to build common functionality from scratch. Save a ton of hours in setting up the projects.

Technical Foundation

The template includes enterprise-grade architecture with Jetpack Compose and Material Design 3, Firebase integration, multiple dashboard options, advanced networking through Retrofit/Ktor, biometric security features, and over 20 pre-built UI components.

Customization

The standout feature is the configurable features_config.json system that lets you pick and choose exactly which components you need, like Firebase services, Google Maps, authentication flows, or testing utilities. The package removal system then strips out everything you don't use, keeping your final app optimized and lightweight.

This approach solves the common problem of boilerplate projects that force you to carry dead weight from unused features while still providing comprehensive functionality when you need it.

Top comments (0)