Skip to main content

Overview

LiquidBounce features a powerful theme system that allows complete customization of the client’s user interface. Themes are built using Svelte and compiled to modern web components that integrate seamlessly with the client’s browser-based UI.
Themes are stored in the themes/ directory and can be loaded from local files, the marketplace, or bundled resources

Theme Manager

The ThemeManager handles theme loading, activation, and browser integration:
object ThemeManager : Config("theme") {
    internal val themesFolder = File(ConfigSystem.rootFolder, "themes")
    val themes: List<Theme>
    var theme: Theme?
    var shaderEnabled by boolean("Shader", false)
}
Source: integration/theme/ThemeManager.kt:47-90

Theme Architecture

Themes follow a specific structure for organization and functionality:
themes/
└── my-theme/
    ├── theme.json       # Theme metadata
    ├── src/             # Svelte source files
    │   ├── App.svelte
    │   ├── routes/
    │   └── components/
    ├── public/          # Static assets
    │   ├── logo.png
    │   └── background.jpg
    └── dist/            # Compiled output
        └── bundle.js
The default LiquidBounce theme is located in src-theme/src

Theme Loading Priority

Themes are loaded in a specific priority order:
1

Local Themes (Highest Priority)

Themes in the themes/ folder (excluding “default”):
themesFolder.listFiles { it.isDirectory }
    ?.forEach { file ->
        if (!file.name.equals("default", true)) {
            Theme.load(Theme.Origin.LOCAL, file.relativeTo(themesFolder))
        }
    }
Reference: ThemeManager.kt:134-146
2

Marketplace Themes

Themes installed from the marketplace:
MarketplaceManager.getSubscribedItemsOfType(MarketplaceItemType.THEME)
    .forEach { item ->
        val installationFolder = item.getInstallationFolder()
        Theme.load(Theme.Origin.MARKETPLACE, relativeFile)
    }
Reference: ThemeManager.kt:149-158
3

Bundled Theme (Fallback)

The default LiquidBounce theme bundled with the client:
suspend fun init() {
    includedTheme = Theme.load(Theme.Origin.RESOURCE, File("liquidbounce"))
}
Reference: ThemeManager.kt:117-120

Theme Origins

Themes can originate from three sources:
enum class Origin(val external: Boolean) {
    RESOURCE(false),      // Bundled with client
    LOCAL(true),          // User's themes folder
    MARKETPLACE(true)     // Downloaded from marketplace
}
External themes can be set as “temporary” for development purposes

Browser Integration

Themes render through an integrated browser backend:
fun openImmediate(
    customScreenType: CustomScreenType? = null,
    markAsStatic: Boolean = false,
    settings: BrowserSettings
): Browser {
    val backend = BrowserBackendManager.backend
    return backend.createBrowser(
        getScreenLocation(customScreenType, markAsStatic).url,
        settings = settings
    )
}
Source: ThemeManager.kt:174-206

Screen Types

Themes can define routes for different screen types:
  • ClickGUI - Module configuration interface
  • HUD - Heads-up display elements
  • Settings - Client settings interface
  • Marketplace - Marketplace browser
  • Account Manager - Account management
  • Custom Screens - Plugin-defined screens
fun getScreenLocation(
    customScreenType: CustomScreenType? = null,
    markAsStatic: Boolean = false
): ScreenLocation {
    val theme = theme.takeIf { theme ->
        customScreenType == null || theme?.isSupported(customScreenType.routeName) == true
    } ?: includedTheme // Fallback to default theme
    
    return ScreenLocation(theme, theme.getUrl(customScreenType?.routeName, markAsStatic))
}
Reference: ThemeManager.kt:216-227

Background System

Themes can provide custom backgrounds with optional shader support:
fun loadBackgroundAsync(): CompletableFuture<Unit> = renderScope.future {
    theme?.loadBackgroundImage()
}

fun drawBackground(context: GuiGraphics, width: Int, height: Int, 
                   mouseX: Int, mouseY: Int, delta: Float): Boolean {
    val background = theme?.backgroundImage ?: return false
    background.draw(context, width, height, mouseX, mouseY, delta)
    return true
}
Reference: ThemeManager.kt:96-106, 237-246

Building Themes

Themes are built using standard web development tools:
1

Install Dependencies

cd themes/my-theme
npm install
Required dependencies:
  • svelte - Component framework
  • vite - Build tool
  • typescript - Type safety (optional)
2

Develop Theme

npm run dev
This starts a development server with hot reload at http://localhost:5173
3

Build Production Bundle

npm run build
Creates optimized bundle in dist/ directory
4

Test in Client

Place the theme in the themes/ folder and reload:
.theme reload

Default Theme Structure

The bundled LiquidBounce theme serves as a reference implementation:
src-theme/
├── public/              # Static assets
├── src/
│   ├── App.svelte      # Root component
│   ├── app.scss        # Global styles
│   ├── colors.scss     # Color palette
│   ├── integration/    # Client integration
│   ├── routes/         # Screen routes
│   │   ├── clickgui/
│   │   ├── hud/
│   │   ├── settings/
│   │   └── marketplace/
│   ├── theme/          # Theme utilities
│   └── util/           # Helper functions
├── svelte.config.js
├── vite.config.ts
└── package.json
Reference: src-theme/src/ directory structure

Client Integration API

Themes can interact with the client through the integration API:
// Get all modules
const modules = await window.client.getModules();

// Toggle module
await window.client.toggleModule("KillAura");

// Get module settings
const settings = await window.client.getModuleSettings("KillAura");

// Update setting
await window.client.updateSetting("KillAura", "Range", 4.5);

Svelte Stores

Use Svelte stores for reactive state management:
import { writable, derived } from 'svelte/store';

// Module store
export const modules = writable([]);

// Filter enabled modules
export const enabledModules = derived(
    modules,
    $modules => $modules.filter(m => m.enabled)
);

// Load modules from client
async function loadModules() {
    const data = await window.client.getModules();
    modules.set(data);
}

Theme Customization

Customize colors, fonts, and styles:
// colors.scss
$primary: #00a8ff;
$secondary: #6c757d;
$success: #28a745;
$danger: #dc3545;
$warning: #ffc107;
$info: #17a2b8;

$background: #0a0e27;
$surface: #1a1f3a;
$text: #ffffff;
$text-secondary: #a0aec0;

Resource Management

The theme manager handles resource reloading:
internal val reloader = ResourceManagerReloadListener { resourceManager ->
    themes.forEach { it.onResourceManagerReload(resourceManager) }
    logger.info("Reloaded ${themes.size} themes.")
}
Reference: ThemeManager.kt:108-111

Best Practices

Use Reactive Stores

Leverage Svelte’s reactivity for automatic UI updates

Optimize Assets

Compress images and minify CSS/JS for faster loading

Support All Routes

Implement all required screen types for full compatibility

Test Responsively

Ensure themes work at different resolutions

Follow Design System

Maintain consistent spacing, colors, and typography

Document Features

Include README with theme features and customization
Themes have access to the client integration API. Only load themes from trusted sources.

Publishing Themes

Share your theme on the LiquidBounce Marketplace:
  1. Build production bundle
  2. Create theme.json with metadata
  3. Package theme directory
  4. Submit to marketplace with:
    • Screenshots
    • Description
    • Version info
    • Supported routes

Development Tips

Use temporary theme loading for rapid iteration:
ThemeManager.theme = Theme.load(Theme.Origin.LOCAL, File("dev-theme"))
Access browser DevTools for debugging:
  • Press F12 to open DevTools
  • Use console.log() for debugging
  • Inspect elements and network requests
Enable type safety for better development experience:
interface Module {
    name: string;
    category: string;
    enabled: boolean;
    settings: Record<string, any>;
}

Next Steps

Modules

Learn about the module system

Scripts

Extend themes with custom scripts

Theme Examples

Explore complete theme examples

API Reference

Complete theme API documentation

Build docs developers (and LLMs) love