
Loads Google Fonts families into Compose UIs, returning a fallback while fonts load; keeps fallback on failure, caches loaded fonts to avoid flicker, and fetches files on demand.
Use any Google Font in Android and Compose Multiplatform apps, either downloaded while your app runs or bundled into your app at build time.
"Inter" or "Open Sans" while your app runs with one composable call.GoogleFonts.Inter, with names checked by the compiler.--offline and clean builds working.There are two ways to use Google Fonts, and you can use either or both:
Add the library to commonMain:
repositories {
mavenCentral()
}
kotlin {
sourceSets {
commonMain.dependencies {
implementation("com.composables:google-fonts:0.4.0")
}
}
}Display text in a Google Font downloaded while the app runs, by passing the family returned by rememberGoogleFontFamily() to Text:
import com.composables.googlefonts.rememberGoogleFontFamily
@Composable
fun Greeting(fontName: String) {
val family = rememberGoogleFontFamily(fontName, 400, 700)
Text("Hello, $fontName", fontFamily = family)
}The text renders in FontFamily.SansSerif until the font finishes downloading, then switches to it. Without weights, only weight 400 is downloaded. On Android, iOS and desktop, downloaded fonts are cached on the device.
Download the italic face of every weight alongside the regular ones, by passing italic = true:
val inter = rememberGoogleFontFamily("Inter", 400, 700, italic = true)
Text("Emphasis", fontFamily = inter, fontStyle = FontStyle.Italic)The family then renders both upright and italic text, picking the face that matches fontStyle.
Keep your own font on screen while a Google Font downloads, or if it fails to download, by passing it as fallback:
val lora = rememberGoogleFontFamily("Lora", fallback = FontFamily.Serif)Add Maven Central to pluginManagement.repositories in your settings.gradle.kts:
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}Then apply the plugin in your Android, Compose Multiplatform or Compose Desktop module:
plugins {
// Your existing Android or Kotlin and Compose plugins.
id("com.composables.google-fonts") version "0.4.0"
}Compose Multiplatform modules need the org.jetbrains.compose plugin; the Google Fonts plugin adds the Compose resources dependency for you.
Display text in Inter bundled with your app, by listing it in the googleFonts block of your module's build file:
googleFonts {
family("Inter") {
weights(400, 700)
}
}Build the module, then pass the generated GoogleFonts.Inter to Text:
import com.example.app.fonts.GoogleFonts
Text("Hello, Inter", fontFamily = GoogleFonts.Inter)GoogleFonts is generated in your module's package: <namespace>.fonts in Android modules, or <group>.<module name>.fonts in Compose Multiplatform and Desktop modules. A family without weights(...) includes only weight 400.
Bundle the italic face of every listed weight alongside the regular ones, by calling italic() in the family block:
googleFonts {
family("Inter") {
weights(400, 700)
italic()
}
}GoogleFonts.Inter then renders both upright and italic text, picking the face that matches fontStyle.
Access a bundled family under your own name, by setting accessor in its family block:
googleFonts {
family("Playfair Display") {
accessor = "Heading"
}
}The family is then available as GoogleFonts.Heading instead of GoogleFonts.PlayfairDisplay.
Import bundled fonts from a package of your choice, by setting packageName in the googleFonts block:
googleFonts {
packageName.set("com.example.design.fonts")
family("Inter")
}Avoid a fallback font on the first frame of a Wasm app, by showing your UI only once GoogleFonts.preload() returns true:
import com.example.app.fonts.GoogleFonts
import com.example.app.fonts.preload
@Composable
fun WebApp() {
if (GoogleFonts.preload()) {
App()
}
}Browsers still fetch bundled fonts from your host, so without preloading Compose can show a fallback while they arrive.
The plugin writes a google-fonts.lock file beside your module's build file. It pins each font and license file by checksum, so commit it.
To fetch a newer version of one face, remove all lockfile lines starting with its resource name, such as googlefonts_inter_400_normal, and rebuild. Delete the lockfile to update every font.
The plugin merges its fonts with your src/commonMain/composeResources folder. If your module keeps common resources somewhere else, the plugin needs to know where so it can merge them into the generated resources.
Set resourcesDirectory instead of calling compose.resources.customDirectory("commonMain", ...):
googleFonts {
resourcesDirectory.set(layout.projectDirectory.dir("resources/common"))
}res/font resources and licenses go to assets/googleFonts/licenses/; no Compose resources dependency is needed.files/googleFonts/licenses/.~/.gradle/caches/com.composables.google-fonts/v1/, including after clean and with --offline.Use any Google Font in Android and Compose Multiplatform apps, either downloaded while your app runs or bundled into your app at build time.
"Inter" or "Open Sans" while your app runs with one composable call.GoogleFonts.Inter, with names checked by the compiler.--offline and clean builds working.There are two ways to use Google Fonts, and you can use either or both:
Add the library to commonMain:
repositories {
mavenCentral()
}
kotlin {
sourceSets {
commonMain.dependencies {
implementation("com.composables:google-fonts:0.4.0")
}
}
}Display text in a Google Font downloaded while the app runs, by passing the family returned by rememberGoogleFontFamily() to Text:
import com.composables.googlefonts.rememberGoogleFontFamily
@Composable
fun Greeting(fontName: String) {
val family = rememberGoogleFontFamily(fontName, 400, 700)
Text("Hello, $fontName", fontFamily = family)
}The text renders in FontFamily.SansSerif until the font finishes downloading, then switches to it. Without weights, only weight 400 is downloaded. On Android, iOS and desktop, downloaded fonts are cached on the device.
Download the italic face of every weight alongside the regular ones, by passing italic = true:
val inter = rememberGoogleFontFamily("Inter", 400, 700, italic = true)
Text("Emphasis", fontFamily = inter, fontStyle = FontStyle.Italic)The family then renders both upright and italic text, picking the face that matches fontStyle.
Keep your own font on screen while a Google Font downloads, or if it fails to download, by passing it as fallback:
val lora = rememberGoogleFontFamily("Lora", fallback = FontFamily.Serif)Add Maven Central to pluginManagement.repositories in your settings.gradle.kts:
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}Then apply the plugin in your Android, Compose Multiplatform or Compose Desktop module:
plugins {
// Your existing Android or Kotlin and Compose plugins.
id("com.composables.google-fonts") version "0.4.0"
}Compose Multiplatform modules need the org.jetbrains.compose plugin; the Google Fonts plugin adds the Compose resources dependency for you.
Display text in Inter bundled with your app, by listing it in the googleFonts block of your module's build file:
googleFonts {
family("Inter") {
weights(400, 700)
}
}Build the module, then pass the generated GoogleFonts.Inter to Text:
import com.example.app.fonts.GoogleFonts
Text("Hello, Inter", fontFamily = GoogleFonts.Inter)GoogleFonts is generated in your module's package: <namespace>.fonts in Android modules, or <group>.<module name>.fonts in Compose Multiplatform and Desktop modules. A family without weights(...) includes only weight 400.
Bundle the italic face of every listed weight alongside the regular ones, by calling italic() in the family block:
googleFonts {
family("Inter") {
weights(400, 700)
italic()
}
}GoogleFonts.Inter then renders both upright and italic text, picking the face that matches fontStyle.
Access a bundled family under your own name, by setting accessor in its family block:
googleFonts {
family("Playfair Display") {
accessor = "Heading"
}
}The family is then available as GoogleFonts.Heading instead of GoogleFonts.PlayfairDisplay.
Import bundled fonts from a package of your choice, by setting packageName in the googleFonts block:
googleFonts {
packageName.set("com.example.design.fonts")
family("Inter")
}Avoid a fallback font on the first frame of a Wasm app, by showing your UI only once GoogleFonts.preload() returns true:
import com.example.app.fonts.GoogleFonts
import com.example.app.fonts.preload
@Composable
fun WebApp() {
if (GoogleFonts.preload()) {
App()
}
}Browsers still fetch bundled fonts from your host, so without preloading Compose can show a fallback while they arrive.
The plugin writes a google-fonts.lock file beside your module's build file. It pins each font and license file by checksum, so commit it.
To fetch a newer version of one face, remove all lockfile lines starting with its resource name, such as googlefonts_inter_400_normal, and rebuild. Delete the lockfile to update every font.
The plugin merges its fonts with your src/commonMain/composeResources folder. If your module keeps common resources somewhere else, the plugin needs to know where so it can merge them into the generated resources.
Set resourcesDirectory instead of calling compose.resources.customDirectory("commonMain", ...):
googleFonts {
resourcesDirectory.set(layout.projectDirectory.dir("resources/common"))
}res/font resources and licenses go to assets/googleFonts/licenses/; no Compose resources dependency is needed.files/googleFonts/licenses/.~/.gradle/caches/com.composables.google-fonts/v1/, including after clean and with --offline.